Unified, opinionated CLI wrapper for API specification tooling.
npm install @bymbly/api-toolsUnified, opinionated CLI wrapper for API specification tooling.
Standardizes common workflows across projects with sensible defaults while allowing full
customization through CLI options and passthrough arguments.
Supports: OpenAPI, AsyncAPI, Arazzo
Wraps: AsyncAPI | Redocly | Spectral



- Single unified CLI - One tool for all API spec operations
- Opinionated defaults - Sensible conventions for file locations and configurations
- Consistent interface - Same flags and patterns across all commands
- Flexible overrides - CLI options for common cases, passthrough for advanced use
- Bundled configs - Default Spectral and Redocly configuration included
- Auto-detection - Finds OpenAPI, AsyncAPI, and Arazzo specs automatically
- @bymbly/api-tools
- Features
- Table of Contents
- Installation
- Quick Start
- Command Structure
- Global Options
- Commands
- AsyncAPI Commands
- asyncapi build-docs
- asyncapi bundle
- asyncapi format
- asyncapi generate docs
- asyncapi generate from-template
- asyncapi lint
- Redocly Commands
- redocly build-docs
- redocly bundle
- redocly generate-arazzo
- redocly init
- redocly join
- redocly lint
- redocly respect
- Spectral Commands
- spectral init
- spectral lint
- Default File Locations
- Configuration Files
- Auto-Discovery
- Bundled Defaults
- Custom Configs
- Passthrough Arguments
- CI/CD Integration
- GitHub Actions Example
- Common Workflows
- Development
- Pre-commit
- CI Pipeline
- API Testing
- Troubleshooting
- Command not found
- Config not found
- Bundled config issues
- Contributing
- License
``bash`
npm install -D @bymbly/api-tools@latest
Add scripts to your package.json:
`json`
{
"scripts": {
"lint": "npm run lint:spectral && npm run lint:redocly && npm run lint:asyncapi",
"lint:spectral": "api-tools spectral lint",
"lint:redocly": "api-tools redocly lint",
"lint:asyncapi": "api-tools asyncapi lint",
"bundle:openapi": "api-tools redocly bundle",
"bundle:asyncapi": "api-tools asyncapi bundle",
"join": "api-tools redocly join",
"docs:openapi": "api-tools redocly build-docs",
"docs:asyncapi": "api-tools asyncapi build-docs",
"arazzo:gen": "api-tools redocly generate-arazzo",
"test:api": "api-tools redocly respect"
}
}
Run:
`bash`
npm run lint # Lint with both Spectral and Redocly
npm run bundle:openapi # Bundle OpenAPI documents
npm run bundle:asyncapi # Bundle AsyncAPI documents
npm run join # Join OpenAPI documents
npm run docs:openapi # Generate OpenAPI HTML documentation
npm run docs:asyncapi # Generate AsyncAPI HTML documentation
npm run arazzo:gen # Generate Arazzo workflow starter
npm run test:api # Execute Arazzo workflow tests
`bash`
api-tools [global-options]
Available for all commands:
- --quiet - Disable wrapper logging (still shows tool output)--silent
- - Disable all output (wrapper + tool)--cwd
- - Run as if started in this directory
#### asyncapi build-docs
Alias for asyncapi generate docs - builds HTML documentation from AsyncAPI documents.
`bash`
api-tools asyncapi build-docs [input] [options]
See asyncapi generate docs for full usage details.
#### asyncapi bundle
Bundle AsyncAPI documents into a single file.
Usage:
`bash`
api-tools asyncapi bundle [input] [options]
Options:
- [input] - Document path (default: asyncapi/asyncapi.yaml)--output
- - Output file path (default: dist/bundle/asyncapi.yaml)--ext
- - Output extension (overrides --output extension)json
- Choices: , yaml, yml--x-origin
- - Generate x-origin fields with dereferenced $ref history
Examples:
`bashBundle with defaults
api-tools asyncapi bundle
####
asyncapi formatConvert AsyncAPI documents between formats (YAML <---> JSON).
Usage:
`bash
api-tools asyncapi format [input] [options]
`Options:
-
[input] - Document path (default: asyncapi/asyncapi.yaml)
- --output - Output file path (default: dist/format/asyncapi.json)
- --ext - Output extension (overrides --output extension)
- Choices: json, yaml, ymlExamples:
`bash
Convert to JSON (default)
api-tools asyncapi formatConvert to YAML
api-tools asyncapi format --ext yamlCustom input and output
api-tools asyncapi format input.json --output output.yaml
`####
asyncapi generate docsfrom-template with HTML template).Usage:
`bash
api-tools asyncapi generate docs [input] [options]
`Options:
-
[input] - Document path (default: asyncapi/asyncapi.yaml)
- --output - Output HTML file (default: dist/docs/asyncapi.html)
- --params - Template parameters (can be repeated)
- --single-file - Generate single HTML file (default: true)
- --no-single-file - Generate multiple filesExamples:
`bash
Generate single-file docs
api-tools asyncapi generate docsGenerate multi-file docs
api-tools asyncapi generate docs --no-single-fileCustom output and parameters
api-tools asyncapi generate docs --output public/api.html \
--params version=2.0.0
`####
asyncapi generate from-templateGenerate code or documentation from AsyncAPI documents using templates.
Usage:
`bash
api-tools asyncapi generate from-template [input] [options]
`Options:
-
- REQUIRED. Template name or URL (e.g., @asyncapi/html-template)
- [input] - Document path (default: asyncapi/asyncapi.yaml)
- --output - Output directory (default: dist/generated/)
- --params - Template parameters (can be repeated)
- --force-write - Overwrite existing filesExamples:
`bash
Generate HTML docs
api-tools asyncapi generate from-template @asyncapi/html-templateGenerate with custom output
api-tools asyncapi generate from-template @asyncapi/nodejs-template \
--output src/generatedGenerate with parameters
api-tools asyncapi generate from-template @asyncapi/java-spring-template \
--params javaPackage=com.example.myapp.codegen maven=true
`####
asyncapi lintValidate and lint AsyncAPI documents.
Usage:
`bash
api-tools asyncapi lint [input] [options]
`Options:
-
[input] - Document path (default: asyncapi/asyncapi.yaml)
- --format - Output format (default: stylish)
- Choices: json, stylish, junit, html, teamcity, pretty, github-actions, sarif,
code-climate, gitlab, markdown
- --output - Write output to file
- --fail-severity - Fail threshold (default: warn)
- Choices: error, warn, info, hintExamples:
`bash
Lint default AsyncAPI spec
api-tools asyncapi lintLint specific file
api-tools asyncapi lint custom/spec.yamlJSON output
api-tools asyncapi lint --format json --output results.jsonOnly fail on errors
api-tools asyncapi lint --fail-severity error
`$3
####
redocly build-docsBuild HTML documentation from OpenAPI documents.
Usage:
`bash
api-tools redocly build-docs [input] [options]
`Options:
-
[input] - OpenAPI document path (default: openapi/openapi.yaml)
- --output - Output HTML file (default: dist/docs/openapi.html)
- --config - Config file path (overrides auto/bundled)Examples:
`bash
Generate docs with defaults
api-tools redocly build-docsCustom output location
api-tools redocly build-docs --output public/api-docs.htmlCustom title via passthrough
api-tools redocly build-docs -- --title "My API Documentation"
`####
redocly bundleBundle API descriptions into a single file.
> Note: The
bundle command differs from the join command.
> The bundle command takes a root OpenAPI file as input and follows the $ref mentions to include
> all the referenced components into a single output file. The join command can combine multiple
> OpenAPI files into a single unified API description file.Usage:
`bash
api-tools redocly bundle [input] [options]
`Options:
-
[input] - Document path (default: openapi/openapi.yaml)
- --output - Output file path (default: dist/bundle/openapi.yaml)
- --ext - Output extension (overrides --output extension)
- Choices: json, yaml, yml
- --dereferenced - Generate fully dereferenced bundle (no $ref)
- --config - Config file path (overrides auto/bundled)Examples:
`bash
Bundle with defaults
api-tools redocly bundleBundle to JSON
api-tools redocly bundle --ext jsonFully dereferenced bundle
api-tools redocly bundle --dereferencedCustom output
api-tools redocly bundle --output dist/api-bundle.yamlRemove unused components via passthrough
api-tools redocly bundle -- --remove-unused-components
`####
redocly generate-arazzoGenerate Arazzo workflow description from OpenAPI document.
Usage:
`bash
api-tools redocly generate-arazzo [input] [options]
`Options:
-
[input] - OpenAPI document path (default: openapi/openapi.yaml)
- --output - Output file path (default: arazzo/auto-generated.arazzo.yaml)Note: Generated Arazzo files require manual editing to be functional.
Examples:
`bash
Generate from default OpenAPI
api-tools redocly generate-arazzoCustom output
api-tools redocly generate-arazzo --output arazzo/workflows.arazzo.yaml
`####
redocly initCreate a default
redocly.yaml config file.`bash
api-tools redocly init [--force]
`####
redocly joinJoin multiple OpenAPI 3.x documents into a single file.
> Note: The
join command differs from the bundle command.
> The bundle command takes a root OpenAPI file as input and follows the $ref mentions to include
> all the referenced components into a single output file. The join command can combine multiple
> OpenAPI files into a single unified API description file.
> Unlike the bundle command, join does not execute preprocessors or decorators and combines the
> API description files as-is without modifying the original source files.Usage:
`bash
api-tools redocly join [options]
`Options:
-
- REQUIRED. At least 2 document paths to join
- --output - Output file path (default: dist/join/openapi.yaml)
- --prefix-components-with-info-prop - Prefix component names with info property to
resolve conflicts (e.g., version, title)
- --prefix-tags-with-info-prop - Prefix tag names with info property (e.g., title, version)
- --prefix-tags-with-filename - Prefix tag names with filename to resolve conflicts
- --without-x-tag-groups - Skip automated x-tagGroups creation (avoids tag duplication)
- --config - Config file path (overrides auto/bundled)> Note: The options
--prefix-tags-with-info-prop, --prefix-tags-with-filename, and
> --without-x-tag-groups are mutually exclusive.Examples:
`bash
Join two documents
api-tools redocly join api-1.yaml api-2.yamlJoin with custom output
api-tools redocly join users-api.yaml orders-api.yaml \
--output dist/combined-api.yamlResolve component naming conflicts using version
api-tools redocly join museum-v1.yaml museum-v2.yaml \
--prefix-components-with-info-prop versionPrefix tags with title to avoid conflicts
api-tools redocly join first-api.yaml second-api.yaml \
--prefix-tags-with-info-prop titlePrefix tags with filename
api-tools redocly join api1/openapi.yaml api2/openapi.yaml \
--prefix-tags-with-filenameSkip x-tagGroups for duplicate tags
api-tools redocly join api-a.yaml api-b.yaml --without-x-tag-groupsAdvanced passthrough options
api-tools redocly join *.yaml -- --lint-config error
`####
redocly lintValidate and lint OpenAPI, AsyncAPI, and Arazzo documents using Redocly.
Usage:
`bash
api-tools redocly lint [input] [options]
`Options:
-
[input] - Document path (default: auto-detect)
- --openapi - Lint only OpenAPI at openapi/openapi.yaml
- --asyncapi - Lint only AsyncAPI at asyncapi/asyncapi.yaml
- --arazzo - Lint only Arazzo at arazzo/arazzo.yaml
- --format - Output format (default: codeframe)
- Choices: codeframe, stylish, json, checkstyle, codeclimate, github-actions, markdown, summary
- --config - Config file path (overrides auto/bundled)Examples:
`bash
Auto-detect and lint all specs
api-tools redocly lintLint only OpenAPI
api-tools redocly lint --openapiJSON output
api-tools redocly lint --format jsonCustom config
api-tools redocly lint --config custom-redocly.yaml
`####
redocly respectExecute Arazzo workflow tests.
Usage:
`bash
api-tools redocly respect [input] [options]
`Options:
-
[input] - Arazzo document path (default: arazzo/arazzo.yaml)
- --workflow - Run only specified workflows
- --skip - Skip specified workflows (conflicts with --workflow)
- --verbose - Enable verbose output
- --input - Workflow input parameters (key=value or JSON)
- --server - Server overrides (name=url)
- --json-output - Save results to JSON file
- --har-output - Save HTTP interactions to HAR fileExamples:
`bash
Execute default workflows
api-tools redocly respectRun specific workflow
api-tools redocly respect --workflow login-flowTest against staging
api-tools redocly respect --server api=https://staging.example.comProvide inputs
api-tools redocly respect --input email=test@example.com --input password=secretCI/CD with JSON output
api-tools redocly respect --json-output results.json --verboseAdvanced options via passthrough
api-tools redocly respect -- --max-steps 100 --severity '{"STATUS_CODE_CHECK":"warn"}'
`$3
####
spectral initCreate a default
spectral.yaml config file.`bash
api-tools spectral init [--force]
`####
spectral lintValidate and lint OpenAPI, AsyncAPI, and Arazzo documents.
Usage:
`bash
api-tools spectral lint [input] [options]
`Options:
-
[input] - Document path (default: auto-detect)
- --openapi - Lint only OpenAPI at openapi/openapi.yaml
- --asyncapi - Lint only AsyncAPI at asyncapi/asyncapi.yaml
- --arazzo - Lint only Arazzo at arazzo/arazzo.yaml
- --format - Output format (default: stylish)
- Choices: json, stylish, junit, html, text, teamcity, pretty, github-actions, sarif, markdown, gitlab
- --output - Write output to file
- --ruleset - Custom ruleset (overrides auto/bundled)
- --fail-severity - Fail threshold (default: warn)
- Choices: error, warn, info, hint
- --display-only-failures - Show only failing results
- --verbose - Enable verbose outputExamples:
`bash
Auto-detect and lint all specs
api-tools spectral lintLint specific spec types
api-tools spectral lint --openapi
api-tools spectral lint --asyncapi --arazzoLint specific file
api-tools spectral lint custom/spec.yamlJSON output
api-tools spectral lint --format json --output results.jsonCustom ruleset
api-tools spectral lint --ruleset .spectral.yamlPassthrough advanced options
api-tools spectral lint -- --ignore-unknown-format
`Default File Locations
The tool expects the following directory structure:
`bash
project/
├── openapi/
│ └── openapi.yaml # Main OpenAPI spec
├── asyncapi/
│ └── asyncapi.yaml # Main AsyncAPI spec
├── arazzo/
│ ├── arazzo.yaml # Production Arazzo workflows
│ └── auto-generated.arazzo.yaml # Generated starter
└── dist/
├── bundle/
│ ├── openapi.yaml # OpenAPI bundled output
│ └── asyncapi.yaml # AsyncAPI bundled output
├── format/
│ └── asyncapi.json # AsyncAPI format output
├── generated/ # AsyncAPI template output
├── join/
│ └── openapi.yaml # Joined output
└── docs/
├── openapi.html # OpenAPI docs
└── asyncapi.html # AsyncAPI docs (or asyncapi/ for multi-file)
`Configuration Files
$3
The tool automatically discovers local config files:
-
.spectral.yaml, .spectral.yml, .spectral.json, .spectral.js, .spectral.mjs,
spectral.yaml, spectral.yml, spectral.json, spectral.js, spectral.mjs
- .redocly.yaml, .redocly.yml, redocly.yaml, redocly.yml$3
If no local config exists, opinionated bundled configs are used with stricter-than-default rules:
- Spectral:
defaults/spectral.yaml - Comprehensive OpenAPI/AsyncAPI/Arazzo validation
- Redocly: defaults/redocly.yaml - Strict API design standardsThese bundled configs enforce best practices and may be more restrictive than upstream tool defaults.
Create a local config file to customize rules for your project.
$3
Override with CLI options:
`bash
api-tools spectral lint --ruleset custom/.spectral.yaml
api-tools redocly lint --config custom/redocly.yaml
`Passthrough Arguments
For advanced options not exposed by the wrapper, use
-- to pass arguments directly to the underlying tool:`bash
Spectral advanced options
api-tools spectral lint -- --ignore-unknown-formatRedocly advanced options
api-tools redocly bundle -- --remove-unused-components
api-tools redocly respect -- --max-steps 100 --execution-timeout 1800000
`CI/CD Integration
$3
`yaml
name: API Validationon: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: actions/setup-node@v6
with:
node-version: "24"
- name: Install dependencies
run: npm ci
env:
GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_PACKAGES_TOKEN }}
- name: Lint with Spectral
run: npm run lint:spectral -- --format github-actions
- name: Lint with Redocly
run: npm run lint:redocly -- --format github-actions
- name: Bundle spec
run: npm run bundle
- name: Generate docs
run: npm run docs
- name: Test workflows
run: npm run test:api -- --verbose
# Alternative: Call CLI directly (useful for matrix builds or custom workflows)
# - name: Lint OpenAPI with Spectral
# run: npx api-tools spectral lint --openapi --format github-actions
# Optional: Save results as artifacts
- name: Generate test report
if: always()
run: npm run test:api -- --json-output results.json
- name: Upload test results
if: always()
uses: actions/upload-artifact@v6
with:
name: api-test-results
path: results.json
`Common Workflows
$3
`bash
Lint using Spectral during development
api-tools spectral lint --openapiLint using Redocly during development
api-tools redocly lint --openapiLint AsyncAPI during development
api-tools asyncapi lintGenerate docs for local preview
api-tools redocly build-docs
api-tools asyncapi build-docs
`$3
`bash
Fast validation
api-tools spectral lint
api-tools redocly lint
api-tools asyncapi lint
`$3
`bash
Full validation with outputs
api-tools spectral lint --format github-actions
api-tools redocly lint --format github-actions
api-tools asyncapi lint --format github-actions
api-tools redocly bundle --output dist/openapi.yaml
api-tools asyncapi bundle --output dist/asyncapi.yaml
api-tools redocly build-docs --output dist/api-docs.html
api-tools asyncapi build-docs --output dist/asyncapi-docs.html
`$3
`bash
Run Arazzo workflows against staging
api-tools redocly respect \
--server api=https://staging.example.com \
--input apiKey=${STAGING_API_KEY} \
--json-output test-results.json \
--verboseBundle AsyncAPI for deployment
api-tools asyncapi bundle --output dist/asyncapi-production.yamlConvert AsyncAPI to JSON for tooling
api-tools asyncapi format --ext json --output dist/asyncapi.json
`Troubleshooting
$3
Ensure the package is installed and npm scripts are configured:
`bash
npm install -D @bymbly/api-tools@latest
`$3
Check config file names and locations. Use
--config or --ruleset` to specify custom paths.To use your own config instead of bundled defaults, create a local config file that will be auto-discovered.
Issues and pull requests welcome at github.com/bymbly/api-tools!