swagger2openapi
swagger2openapi converts Swagger 2.0 API descriptions into OpenAPI 3.0.x documents. It is both a CommonJS Node library and a command-line program that accepts JSON or YAML from a file or URL, rewrites definitions, parameters, request bodies, responses, security schemes, servers, references, and selected vendor extensions, then emits JSON or YAML. The package also installs `oas-validate` and `boast` utilities from the broader OAS-Kit toolset.
It remains a capable one-purpose migration tool for Swagger 2.0 to OpenAPI 3.0, especially when references and real-world extensions matter. Treat it as a conversion step to review and retire, not as the foundation of a new OpenAPI toolchain.
Use it if
- You have a large Swagger 2.0 document and need a repeatable OpenAPI 3.0 conversion rather than a manual rewrite
- You need to preserve most references instead of fully dereferencing the document during conversion
- You need a Node API for objects, strings, files, streams, or URLs with callback and promise styles
- Your legacy definitions use supported Microsoft, Amazon API Gateway, swaggerplusplus, or Apiary extensions
- You need OpenAPI 3.1 output: version 7 tracks the 3.0.x specification and defaults to 3.0.0, so it is not a 3.1 migration tool
- You want an actively evolving converter: npm 7.0.8 was published in July 2021 and the repository's last push was in October 2023
- You need a small browser dependency: the project documents a 42 KB minified converter shell plus a 172 KB minified converter library in its Webpack build, before your application code
- You need typed ESM APIs: the package exports CommonJS, ships no TypeScript declarations, and returns a mutated options object by default rather than a narrowly typed result
- You are processing untrusted documents with remote resolution enabled: URL input and external `$ref` resolution perform network requests, so the caller must restrict destinations, protocols, agents, and fetch behavior
Setup reality
For project use, install with `npm install --save-dev swagger2openapi`; the README's global install is convenient for a workstation but makes CI versions less reproducible. The package has no peer dependencies or native build, but it has eleven direct dependencies spanning YAML parsing, HTTP fetch, HTTP/2 fetch, resolution, validation, schema walking, and CLI parsing. The command expects a filename or HTTP URL and writes JSON to stdout unless `--outfile` is used; `--yaml` requests YAML, while a `.json` or `.yaml` output extension can override that flag. Swagger 2.0 to OpenAPI 3.0 is not lossless. Body parameters become request bodies, security and media-type concepts move, selected extensions are transformed, and warnings may be attached as vendor extensions when `warnOnly` is enabled. `patch` repairs some invalid input rather than merely reporting it, so review diffs and validate the result. External references are preserved by default; `resolve` fetches them, and `resolveInternal` also dereferences internal references while changing request-body deduplication. Missing external resources are not fatal unless `fatal` is set. Since v6, YAML anchors and aliases are rejected unless `anchors` is explicitly enabled because the project warns they may break conversion. In the Node API, every `convert*` function is asynchronous, callbacks are optional, and the same options object is extended with fields such as `openapi`, `patches`, `externals`, caches, and promise internals. Use a fresh options object per conversion. `direct: true` changes the resolved value from the extended options object to the OpenAPI document itself. For URL and reference handling in a service, provide a controlled `fetch`, `fetchOptions`, protocol handlers, and agent rather than allowing arbitrary outbound access.
Patterns
Convert a Swagger file to JSONconvert-file-cli
npx swagger2openapi swagger.yaml --outfile openapi.jsonThe output extension controls serialization, and the command overwrites the named output file synchronously. Review the generated diff before replacing a source contract.
Write an OpenAPI YAML documentconvert-to-yaml
npx swagger2openapi swagger.json --yaml --outfile openapi.yamlA `.json` output filename turns YAML off and a `.yaml` filename turns it on, regardless of the initial flag value.
Repair minor Swagger errors during conversionpatch-invalid-input
npx swagger2openapi swagger.yaml --patch --outfile openapi.yaml`--patch` changes repairable invalid structures instead of only reporting them. Validate and inspect the result rather than assuming semantic equivalence.
Keep converting after non-patchable errorscollect-warnings
npx swagger2openapi swagger.yaml \
--warnOnly \
--warnProperty x-conversion-warning \
--outfile openapi.yamlWarnings are added to the output as specification extensions, which can leak into generated documentation or code unless removed later.
Resolve external reference filesresolve-external-references
npx swagger2openapi swagger.yaml \
--resolve \
--fatal \
--outfile openapi.yamlWithout `--fatal`, some resolution failures produce empty objects. Do not enable remote resolution on untrusted specs without outbound network controls.
Preserve reference siblings through allOfhandle-ref-siblings
npx swagger2openapi swagger.yaml \
--refSiblings allOf \
--outfile openapi.yaml`allOf` wrapping is intended for schema objects. Outside schemas, the default behavior removes sibling properties next to `$ref`.
Convert an in-memory Swagger objectconvert-object
const converter = require('swagger2openapi');
const result = await converter.convertObj(swagger, {
patch: true,
});
console.log(result.openapi.openapi); // 3.0.0
console.log(result.patches);The options object is modified and returned with the output and internal state. Create a new options object for every conversion.
Resolve directly to the OpenAPI objectreturn-document-directly
const openapi = await converter.convertStr(swaggerText, {
direct: true,
patch: false,
});
console.log(openapi.paths);With `direct: true`, the promise resolves to the document instead of the extended options object, so there is no `result.openapi` wrapper.
Convert a local file from Nodeconvert-file-api
const result = await converter.convertFile('swagger.yaml', {
encoding: 'utf8',
origin: 'https://api.example.com/swagger.yaml',
});
await fs.promises.writeFile(
'openapi.json',
JSON.stringify(result.openapi, null, 2),
);The `origin` option adds an `x-origin` entry. It does not change where relative external references are read from; `source` tracks resolution context.
Convert a URL with a controlled fetch functionconvert-url-safely
const result = await converter.convertUrl(specUrl, {
fetch: async (url, options) => {
const parsed = new URL(url);
if (parsed.hostname !== 'specs.example.com') {
throw new Error('Blocked spec host');
}
return fetch(url, options);
},
fetchOptions: { headers: { Accept: 'application/yaml' } },
});The override also matters when resolving remote resources. Add protocol, address-range, redirect, timeout, and response-size controls for hostile input.
Opt into YAML aliases for a trusted documentallow-yaml-anchors
npx swagger2openapi swagger-with-anchors.yaml \
--anchors \
--outfile openapi.yamlVersion 6 and later reject anchors by default, and the project documentation says allowing them may break conversion. Prefer expanding aliases before conversion.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| @redocly/cli | npm | You want a maintained OpenAPI CLI for linting, bundling, joining, and transforming documents around a modern ruleset |
| swagger-cli | npm | You only need validation and bundling of Swagger or OpenAPI files, not conversion from 2.0 to 3.0 |
| openapi-format | npm | You already have OpenAPI output and need deterministic sorting, filtering, formatting, or cleanup |