swagger2openapi review
swagger2openapi 7.0.8 converts Swagger 2.0 JSON or YAML into an OpenAPI 3.0.x document. The command and CommonJS API can read objects, strings, files, streams, or URLs; rewrite definitions, body parameters, responses, security, media types, servers, references, and selected vendor extensions; then return JSON or YAML. It also installs the `oas-validate` and `boast` commands from OAS-Kit. Version 7 removed AJV as the fallback schema validator. The current 7.0.8 publication is a coordinated resolver, validator, and reftools maintenance release with no separate converter feature recorded in the changelog.
swagger2openapi 7.0.8 installed 42 packages in 3.7 seconds and used 5 MB in our sandbox, with working Node imports, no types, zero audit findings, and a failed browser build. It remains useful as a reviewed Swagger 2.0 to OpenAPI 3.0 migration step, but its 2021 release and lack of 3.1 output make it a poor base for a new long-lived API toolchain.
We installed it
| Install | ✓ · 3.7s | 42 packages on disk · 5 MB |
| Import | ✓ | ESM import works · require() works · CommonJS package |
| Browser | n/a | could not be bundled for the browser (Node-only code, most likely) |
| Types | — | no TypeScript types found |
| Known vulns | 0 | 0 critical · 0 high · 0 moderate · 0 low (npm audit) |
Answers from our run
Does swagger2openapi install cleanly?
Yes. In a fresh container with an empty cache, npm install swagger2openapi finished in 4 seconds, leaving 42 packages and 5 MB on disk. npm audit reported no known vulnerabilities.
Can swagger2openapi run in a browser?
Not directly: esbuild could not bundle it for the browser in our run, which normally means it depends on Node built-ins. Use it on the server, or find a browser-targeted alternative.
Does swagger2openapi work with both ESM and CommonJS?
Yes. Both import 'swagger2openapi' and require('swagger2openapi') worked in Node 22 in our run. The package is published as CommonJS.
Does swagger2openapi include TypeScript types?
No type declarations were found in our install, so TypeScript users need their own declarations.
swagger2openapi or @redocly/cli: which should you use?
@redocly/cli: Choose it for current OpenAPI linting, bundling, joining, and transformation after or instead of a one-time Swagger conversion. swagger2openapi 7.0.8 installed 42 packages in 3.7 seconds and used 5 MB in our sandbox, with working Node imports, no types, zero audit findings, and a failed browser build.
When should you not use swagger2openapi?
The target is OpenAPI 3.1. Version 7 tracks the 3.0.x line and defaults to 3.0.0, so another migration step would still be required.
Use it if
- A maintained system still owns Swagger 2.0 contracts and needs repeatable OpenAPI 3.0 output for a reviewed migration.
- Conversion should preserve most `$ref` links instead of flattening every definition into one object graph.
- A Node workflow needs the same conversion through files, URLs, strings, streams, and in-memory objects.
- The source contains one of the documented Microsoft, API Gateway, Apiary, or swaggerplusplus extensions handled by OAS-Kit.
- The target is OpenAPI 3.1. Version 7 tracks the 3.0.x line and defaults to 3.0.0, so another migration step would still be required.
- New tooling requires an active release stream. npm 7.0.8 shipped in July 2021 and the OAS-Kit monorepo was last pushed in October 2023.
- The API must provide first-party types or native ESM exports. This CommonJS package has no declarations or exports map, and it mutates its options object.
- Conversion will run in a browser bundle. Our esbuild browser attempt failed, which matches a package that includes file, stream, URL, resolver, and CLI code.
- Untrusted documents may choose remote URLs or `$ref` targets without egress controls. Resolution performs network requests, creating SSRF, redirect, response-size, and timeout concerns for a service.
Setup reality
We installed swagger2openapi 7.0.8 in a clean Node 22 sandbox in 3.7 seconds. npm installed 42 packages using 5 MB; the package declares 11 direct dependencies, zero peers, 132 KB unpacked, and a BSD-3-Clause license. npm audit returned zero known vulnerabilities. It has no bundled TypeScript declarations. Both CommonJS require() and ESM import worked through interop, while our browser bundle attempt failed. Keep it in a Node CLI or migration service rather than frontend code.
The command accepts a filename or URL and writes JSON to stdout unless an output file or YAML mode is selected. An output filename ending in .json, .yaml, or .yml can decide serialization regardless of an earlier flag. Swagger 2.0 to 3.0 conversion changes object locations and meaning: body parameters become request bodies, media types move, servers are synthesized, and supported extensions may be rewritten. Always validate and diff the generated contract.
External references remain references by default. resolve fetches external targets; resolveInternal also dereferences internal targets and changes request-body reuse. Some missing resources are tolerated unless fatal is set. YAML anchors and aliases are rejected unless anchors is explicitly enabled because the project warns they may disrupt conversion. patch repairs selected invalid structures, while warnOnly can place warning extensions inside the output. Neither mode proves semantic equivalence.
Every convert* path is asynchronous and accepts either a callback or a promise. The options object is extended with the output, patches, external documents, caches, and internal state, so allocate one per conversion. direct: true changes the promise result to the OpenAPI document itself. For URL input or remote refs, supply a restricted fetch implementation with protocol, host, address-range, redirect, timeout, and byte limits instead of trusting document-controlled destinations.
Patterns
Convert a local Swagger file convert-file-to-json
npx swagger2openapi swagger.yaml --outfile openapi.jsonThe `.json` extension selects JSON output. Validate and diff the generated contract before replacing the original source.
Write OpenAPI as YAML convert-file-to-yaml
npx swagger2openapi swagger.json --yaml --outfile openapi.yamlThe output extension can override the YAML flag, so keep the filename and intended serialization consistent.
Repair supported input errors patch-invalid-swagger
npx swagger2openapi swagger.yaml --patch --outfile openapi.yamlPatch mode changes selected invalid structures. A successful command does not prove the repaired API behaves like the source service.
Continue and annotate nonfatal problems store-conversion-warnings
npx swagger2openapi swagger.yaml \
--warnOnly \
--warnProperty x-conversion-warning \
--outfile openapi.yamlWarning extensions become part of the output and can reach documentation or generators until a cleanup step removes them.
Require every external reference to resolve resolve-external-refs
npx swagger2openapi swagger.yaml \
--resolve \
--fatal \
--outfile openapi.yamlFatal mode prevents a missing external resource from being replaced with an empty object. Network destinations still need separate controls.
Wrap schema reference siblings in allOf preserve-ref-siblings
npx swagger2openapi swagger.yaml \
--refSiblings allOf \
--outfile openapi.yamlThe allOf strategy is intended for schema objects. Review non-schema `$ref` siblings because OpenAPI 3.0 reference rules remain restrictive.
Convert an in-memory object and inspect repairs convert-object-with-patches
const converter = require('swagger2openapi');
const result = await converter.convertObj(swagger, {patch: true});
console.log(result.openapi.openapi);
console.log(result.patches);The library returns an extended options object by default. Create a new options literal for each conversion.
Resolve straight to the converted document return-openapi-directly
const openapi = await converter.convertStr(swaggerText, {
direct: true,
patch: false,
});
console.log(openapi.paths);`direct: true` removes the `result.openapi` wrapper and also leaves patch or resolver state out of the resolved value.
Read and convert a file through the API convert-file-from-node
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),
);`origin` adds source metadata. Relative reference resolution follows the library's source context rather than that display value.
Allow only one specification host restrict-url-fetch
const result = await converter.convertUrl(specUrl, {
fetch: async (url, options) => {
const target = new URL(url);
if (target.protocol !== 'https:' || target.hostname !== 'specs.example.com') {
throw new Error('Blocked specification URL');
}
return fetch(url, options);
},
});Host checks alone do not cover DNS rebinding, redirects, timeouts, or response size. Enforce those in the fetch boundary too.
Opt into YAML aliases for one conversion allow-trusted-yaml-anchors
npx swagger2openapi swagger-with-anchors.yaml \
--anchors \
--outfile openapi.yamlVersion 6 and later reject anchors by default. Prefer expanding aliases before conversion when reproducible object identity matters.
Convert an incoming Node stream convert-readable-stream
const result = await converter.convertStream(request, {
source: 'https://specs.example.com/root.yaml',
fatal: true,
});
consumeOpenApi(result.openapi);Set a source when relative references need context. Limit request bytes before handing an untrusted stream to the parser.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| @redocly/cli | npm | Choose it for current OpenAPI linting, bundling, joining, and transformation after or instead of a one-time Swagger conversion. |
| swagger-cli | npm | Use it for validation and bundling when the contract can remain Swagger 2.0 or is already OpenAPI. |
| openapi-format | npm | Choose it after conversion when sorting, filtering, renaming, and deterministic formatting are the remaining tasks. |
| swagger-parser | npm | Use it to parse, validate, bundle, or dereference Swagger documents without changing them to OpenAPI 3.0. |
More cli & tooling guides
chalk · commander · typescript · esbuild · yargs · click · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

