swagger-jsdoc and @apidevtools/swagger-parser serve distinct but complementary roles in the OpenAPI ecosystem. swagger-jsdoc extracts API documentation from JSDoc comments within your source code to generate a Swagger definition file dynamically. In contrast, @apidevtools/swagger-parser focuses on reading, validating, dereferencing, and bundling existing Swagger or OpenAPI files (JSON or YAML). While one creates the specification from code annotations, the other ensures that specification is valid, resolved, and ready for consumption by tools like UI renderers or client generators.
Managing API documentation often requires two distinct steps: creating the specification and ensuring it is valid. swagger-jsdoc and @apidevtools/swagger-parser address these steps separately. Understanding their specific roles helps avoid confusion, as they are not direct competitors but rather tools for different stages of the documentation workflow.
swagger-jsdoc builds your OpenAPI definition by scanning your code for JSDoc comments.
// swagger-jsdoc: Define options
const swaggerJsdoc = require('swagger-jsdoc');
const options = {
definition: {
openapi: '3.0.0',
info: { title: 'My API', version: '1.0.0' },
},
apis: ['./routes/*.js'], // Path to files with JSDoc
};
const swaggerSpec = swaggerJsdoc(options);
// swaggerSpec is now a valid OpenAPI object
@apidevtools/swagger-parser works with specification files that already exist.
// @apidevtools/swagger-parser: Parse an existing file
const SwaggerParser = require('@apidevtools/swagger-parser');
async function loadSpec() {
const api = await SwaggerParser.parse('./swagger.yaml');
console.log('API name: %s, Version: %s', api.info.title, api.info.version);
return api;
}
swagger-jsdoc performs basic validation during generation.
// swagger-jsdoc: Basic validation happens on generation
try {
const spec = swaggerJsdoc(options);
console.log('Specification generated successfully');
} catch (error) {
console.error('JSDoc syntax error:', error);
}
@apidevtools/swagger-parser excels at deep validation and dereferencing.
$ref pointers, even those pointing to external files or URLs.// @apidevtools/swagger-parser: Validate and Dereference
async function validateAndBundle() {
try {
// Validates and resolves all $ref pointers
const api = await SwaggerParser.dereference('./swagger.yaml');
// All external references are now inlined in the 'api' object
console.log('All references resolved');
} catch (error) {
console.error('Specification is invalid:', error);
}
}
swagger-jsdoc fits into the development server or build script.
swagger-ui-express to serve docs at a /docs endpoint.swagger.yaml file manually.// Typical Express setup with swagger-jsdoc
const swaggerUi = require('swagger-ui-express');
const swaggerSpec = swaggerJsdoc(options);
app.use('/docs', swaggerUi.serve, swaggerUi.setup(swaggerSpec));
@apidevtools/swagger-parser fits into CI/CD pipelines or pre-build hooks.
// CI/CD validation script
const SwaggerParser = require('@apidevtools/swagger-parser');
SwaggerParser.validate('./swagger.yaml')
.then(() => console.log('✅ Spec is valid'))
.catch(err => {
console.error('❌ Spec validation failed');
process.exit(1);
});
While they solve different problems, both libraries operate within the OpenAPI ecosystem and share some common goals.
// Both handle OpenAPI versioning
// swagger-jsdoc: Set in options.definition.openapi
// @apidevtools/swagger-parser: Detects version from file content
// @apidevtools/swagger-parser: Output as YAML
const yaml = await SwaggerParser.bundle('./swagger.yaml');
// swagger-jsdoc: Output is JS Object (convertible to YAML/JSON)
const jsonSpec = JSON.stringify(swaggerSpec);
// Both produce output compatible with Swagger UI
// swagger-jsdoc -> direct object
// @apidevtools/swagger-parser -> resolved object
| Feature | swagger-jsdoc | @apidevtools/swagger-parser |
|---|---|---|
| Primary Goal | Generate spec from JSDoc comments | Validate and resolve existing spec files |
| Input Source | Source code files (.js, .ts) | Swagger/OpenAPI files (.yaml, .json) |
| Reference Handling | Limited external ref resolution | Full $ref dereferencing and bundling |
| Validation Depth | Basic structure check on generation | Strict schema validation against standard |
| Best Use Case | Dev servers, keeping docs near code | CI/CD pipelines, spec bundling |
swagger-jsdoc is like a writer 📝 — it helps you draft the documentation as you write your code. It reduces the friction of maintaining a separate documentation file by embedding it in your logic. Choose this for developer experience and speed during active development.
@apidevtools/swagger-parser is like an editor 🔍 — it reviews the finished draft for errors, consistency, and completeness. It ensures that the final document is technically sound and ready for publication. Choose this for reliability, validation, and preparing specs for external consumption.
Final Thought: In many professional setups, you will use both. Use swagger-jsdoc to generate the initial spec from your code during development, then pipe that output into @apidevtools/swagger-parser during your build process to validate and bundle it before deployment. This combination ensures your docs are both easy to maintain and strictly valid.
Choose @apidevtools/swagger-parser when you already have an OpenAPI or Swagger definition file and need to validate its structure, resolve external references ($ref), or bundle it into a single file. It is essential for build pipelines that require strict schema compliance before deploying documentation or generating SDKs. Use this if your spec exists independently of your source code comments.
Choose swagger-jsdoc if you want to maintain your API documentation directly alongside your route handlers using JSDoc comments. It is ideal for teams that prefer keeping documentation close to the implementation logic to reduce drift. Select this when you need to dynamically generate the Swagger JSON at runtime or during a build step from annotated code files.
$ref pointers, including external files and URLs$ref pointers$ref pointers, giving you a normal JavaScript object that's easy to work with$ref pointers to the same value always resolve to the same object instanceSwaggerParser.validate(myAPI, (err, api) => {
if (err) {
console.error(err);
} else {
console.log("API name: %s, Version: %s", api.info.title, api.info.version);
}
});
Or use async/await or Promise syntax instead. The following example is the same as above:
try {
let api = await SwaggerParser.validate(myAPI);
console.log("API name: %s, Version: %s", api.info.title, api.info.version);
} catch (err) {
console.error(err);
}
For more detailed examples, please see the API Documentation
Install using npm:
npm install @apidevtools/swagger-parser
When using Swagger Parser in Node.js apps, you'll probably want to use CommonJS syntax:
const SwaggerParser = require("@apidevtools/swagger-parser");
When using a transpiler such as Babel or TypeScript, or a bundler such as Webpack or Rollup, you can use ECMAScript modules syntax instead:
import * as SwaggerParser from "@apidevtools/swagger-parser";
Swagger Parser supports recent versions of every major web browser. Older browsers may require Babel and/or polyfills.
To use Swagger Parser in a browser, you'll need to use a bundling tool such as Webpack, Rollup, Parcel, or Browserify. Some bundlers may require a bit of configuration, such as setting browser: true in rollup-plugin-resolve.
Full API documentation is available right here
The library, by default, attempts to resolve any files referenced using $ref, without considering file extensions or the location of the files. This can result in Local File Inclusion (LFI), thus, potentially sensitive information disclosure. Developers must be cautious when working with documents from untrusted sources. See here for more details and information on how to mitigate LFI.
I welcome any contributions, enhancements, and bug-fixes. Open an issue on GitHub and submit a pull request.
To test the project locally on your computer:
Clone this repo
git clone https://github.com/APIDevTools/swagger-parser.git
Install dependencies
npm install
Run the tests
npm test
Check the code coverage
npm run coverage
Swagger Parser is 100% free and open-source, under the MIT license. Use it however you want.
This package is Treeware. If you use it in production, then we ask that you buy the world a tree to thank us for our work.
Thanks to these awesome companies for their support of Open Source developers ❤