Skip to content

Scaffold from OpenAPI

routa scaffold reads an OpenAPI document and writes the source contract it describes: one route file per path, a schema module beside it, and the .routa/ metadata that later checks compare against. Run it when you have an agreed API contract and want the TypeScript source to match it.

  • A Routa project. Scaffolding refuses to run outside one.
  • An OpenAPI document with a .yaml, .yml, or .json extension in the project.
  • No OPTIONS operations in the document. Routa generates those at runtime.
  1. Preview the changes. Nothing is written in preview mode, so run this first every time.

    Terminal window
    npx routa scaffold openapi.yaml --preview
  2. Read the change list. Each generated path is marked with what would happen to it.

    Marker Meaning
    + add New file that does not exist yet
    ~ update Tracked generated file whose content would change
    = unchanged Generated file already matches
    ! conflict A file exists at that path that Routa does not track
    - remove Previously generated file no longer described by the document
  3. Resolve every conflict before continuing. Move or rename any file marked ! conflict that you want to keep, since Routa refuses to overwrite files it did not generate.

  4. Apply the changes.

    Terminal window
    npx routa scaffold openapi.yaml --yes
  5. Validate and typecheck the generated source.

    Terminal window
    npm run check

Scaffolding reports what it wrote:

Scaffolded 4 Routa route file(s).
src/routes/users/route.ts
src/routes/users/schemas.ts
src/routes/users/$userId/route.ts
src/routes/users/$userId/schemas.ts
.routa/openapi-baseline.json
.routa/manifest.json
.routa/routes.gen.ts

Generated handlers are stubs. They satisfy the contract and return placeholder data, so routa check passes immediately and you can fill in the service calls one route at a time.

From the document Into source
Path and method src/routes/**/route.ts with a createRoute per method
Parameters input.params, input.query, input.headers, input.cookies
JSON request body input.body
JSON responses Entries in responses, named from status and operationId
components.schemas Shared schema modules referenced by routes
The whole document .routa/openapi-baseline.json

Supported input is deliberately narrow: paths, methods, operationId, path/query/header/ cookie parameters, JSON bodies, JSON responses, and components.schemas. Anything else stays in the source document and is not approximated in TypeScript.

Problem Fix
ROUTA_OPENAPI_UNSUPPORTED_EXTENSION Rename the document to .yaml, .yml, or .json.
ROUTA_OPENAPI_FILE_NOT_FOUND Run from the project root, or pass the path relative to it.
Regeneration requires preview or confirmation. A manifest already exists. Re-run with --preview, then with --yes.
ROUTA_SCAFFOLD_UNMANAGED_FILE A file exists where Routa wants to generate one, and the manifest does not track it. Move or rename yours.
ROUTA_SCAFFOLD_MODIFIED_GENERATED_FILE You edited a generated file. Move the edits into application-owned code, or accept losing them.