Migration from OpenAPI bundle
Inherits hard rules from SKILL.md §Hard rules.
Use this bundle when converting an existing OpenAPI 3.x document into TypeSpec.
Output paths
tsp-openapi3 ... --output-dir <dir>writes generated.tspfiles to the directory you pass in--output-dir. Pick a location that does not collide with the existing OpenAPI source.- After conversion, when you run
tsp compile, the OpenAPI 3 emitter writes back totsp-output/@typespec/openapi3/openapi.yamlby default. That default is in effect unlesstspconfig.yamlsetsemitter-output-dirfor@typespec/openapi3.
Use those two paths when wiring fidelity diffs: the migration command writes .tsp files; the emitter round-trips them back to OpenAPI under tsp-output/.
AutoRest migration deadline
AutoRest retired July 1, 2026 - that date has passed. Any OpenAPI 2.0 (Swagger) or AutoRest-annotated spec that has not migrated to TypeSpec is already past its tooling-support window; treat a remaining AutoRest dependency as a live blocker. Plan the migration alongside the next planned API version cut, not as a last-minute swap.
tsp-openapi3 accepts OpenAPI 3.x only. Swagger 2.0 specs must first be converted to OpenAPI 3.x using a tool such as swagger2openapi:
npx swagger2openapi ./swagger.json -o ./openapi3.yaml
npx tsp-openapi3 ./openapi3.yaml --output-dir ./typespec-output --namespace Contoso.WidgetsVerify the intermediate OpenAPI 3.x output before running tsp-openapi3; constructs that Swagger 2.0 expressed loosely (multi-collection formData, produces/consumes at the operation level, polymorphism via discriminator without oneOf) often need manual touch-up after swagger2openapi.
Pre-conversion checklist
BEFORE running tsp-openapi3:
- Every operation must have an
operationId- the converter crashes on missing IDs (microsoft/typespecissue #4452). - Spec is OpenAPI 3.x, not 2.0 (run
swagger2openapifirst if needed). - Anonymous inline schemas with
descriptionwill lose their description fields (microsoft/typespecissue #6085). - AutoRest
directive:overrides (method renames, parameter flattening) do NOT survive conversion (Azure/autorestissue #4842). Document them externally before conversion.
Known lossy fields
The following are routinely dropped or degraded by tsp-openapi3. Capture them externally before conversion, then reapply them in TypeSpec:
descriptionon inline/anonymous schemas.descriptionon response headers.- Custom
x-extensions outsidex-ms-*andx-typespec-*. - AutoRest directives.
- OpenAPI
exampleswith multiple keys - only the first survives in some emitter versions.
Correct conversion command
Install dependencies first or run through npx:
npx tsp-openapi3 ./existing-openapi.yaml --output-dir ./typespec-output --namespace Contoso.WidgetsThe --namespace argument (optional) sets the root namespace of the generated TypeSpec files; without it, the CLI derives one from the OpenAPI info.title.
The tsp-openapi3 CLI is provided by @typespec/openapi3. Do not use npx @typespec/openapi3 convert; that is not the documented CLI shape for current TypeSpec.
Migration workflow
- Preserve the original OpenAPI file as the baseline contract.
- Convert with
tsp-openapi3. - Create a real TypeSpec project around the generated
.tspsource:package.jsontspconfig.yamlmain.tsp- source folders
- Replace anonymous and repeated shapes with named models.
- Add missing documentation comments.
- Normalize operation names and interfaces.
- Add auth at namespace level.
- Add versioning if the API is public, partner-facing, Azure-facing, or expected to evolve.
- Compile with
npx tsp compile . --warn-as-error. - Diff emitted OpenAPI against the baseline and document intentional differences.
Fidelity checks
Compare:
- Paths and methods.
- Operation IDs.
- Request bodies.
- Response status codes and schemas.
- Error shape.
- Required/optional properties.
- Nullable semantics.
- Enum values.
- Auth schemes and scopes.
- Examples.
Refactor rules after conversion
- Do not blindly accept generated names.
- Do not keep duplicated inline schemas if they represent the same domain concept.
- Do not introduce breaking route or body changes unless the task includes redesign.
- Prefer a compatibility-first migration, then improve in a follow-up version.
- For Azure specs, move toward Azure Core templates rather than preserving hand-authored
x-ms-*patterns forever.
Fidelity verification
After running tsp-openapi3 to convert and then recompiling the TypeSpec back to OpenAPI, run a structural diff between the round-tripped OpenAPI and the original source. Use a schema-aware diff tool:
# pick one
npx openapi-diff ./source-openapi.yaml ./typespec-output/openapi3/openapi.yaml
oasdiff diff ./source-openapi.yaml ./typespec-output/openapi3/openapi.yamlExpected (acceptable) losses:
- Vendor extensions outside the
x-typespec-*andx-ms-*families that TypeSpec doesn't model. - Inline comments and YAML key ordering.
- Cosmetic formatting (anchors, multiline string style, example indentation).
- Inline schema names regenerated from operations (often improved by manual naming after conversion).
Unexpected losses - file these as bugs against your migration, not as acceptable drift:
- Missing operation IDs (or operation IDs that no longer match SDK-generated client method names).
- Dropped or changed response status codes.
- Lost parameter constraints (
minLength,maxLength,pattern,minimum,maximum,enum). - Lost
requiredflags on properties or parameters. - Auth scheme changes, including scope drift.
- Lost or changed
discriminator/ polymorphic relationships. - Changed nullable semantics on response properties.