freshcrate
Home > Frameworks > tsoa-next

tsoa-next

Build type-safe OpenAPI APIs for Node.js using TypeScript decorators with automatic spec generation and validation

Description

Build type-safe OpenAPI APIs for Node.js using TypeScript decorators with automatic spec generation and validation

README

tsoa-next logo tsoa-next

Pronounced soยทuh

OpenAPI-compliant REST APIs using TypeScript and Node

build status npm version Quality Gate Status

Project Lineage

tsoa-next continues the original tsoa project. The original repository and its contributors established the stable TypeScript-first and OpenAPI-first foundation this work builds on. Where historical release notes or migration references still point upstream, they are kept intentionally for provenance.

Goal

  • TypeScript controllers and models as the single source of truth for your API
  • A valid OpenAPI (formerly Swagger) spec (2.0 or 3.0 if you choose ๐Ÿ˜) is generated from your controllers and models, including:
    • Paths (e.g. GET /users)
    • Definitions based on TypeScript interfaces (models)
    • Parameters/model properties marked as required or optional based on TypeScript (e.g. myProperty?: string is optional in the OpenAPI spec)
    • jsDoc supported for object descriptions (most other metadata can be inferred from TypeScript types)
  • Routes are generated for middleware of choice
    • Express, Hapi, and Koa currently supported, other middleware can be supported using a simple handlebars template
    • Validate request payloads

Philosophy

  • Rely on TypeScript type annotations to generate API metadata if possible
  • If regular type annotations aren't an appropriate way to express metadata, use decorators
  • Use jsdoc for pure text metadata (e.g. endpoint descriptions)
  • Minimize boilerplate
  • Models are best represented by interfaces (pure data structures), but can also be represented by classes
  • Runtime validation of tsoa-next should behave as closely as possible to the specifications that the generated OpenAPI 2/3 schema describes. Any differences in validation logic are clarified by logging warnings during the generation of the OpenAPI Specification (OAS) and/or the routes.
    • Please note that by enabling OpenAPI 3 you minimize the chances of divergent validation logic since OpenAPI 3 has a more expressive schema syntax.

External Validators

@Validate(...) adds opt-in runtime authority for external schemas on supported controller method parameters.

  • Supported forms: @Validate(schema), @Validate('zod', schema), @Validate({ kind: 'zod', schema })
  • Supported libraries: zod, joi, yup, superstruct, io-ts
  • io-ts installs: add fp-ts, and add io-ts-types as well if you rely on helpers like withMessage
  • Supported parameter decorators: @Body, @BodyProp, @Query, @Queries, @Path, @Header, and @FormField / uploaded file params
  • Behavior: TypeScript metadata still drives OpenAPI generation, while the external schema replaces built-in runtime validation for the decorated parameter subtree
  • Compatibility: routes without @Validate(...) keep their current behavior

Generated RegisterRoutes(...) functions also accept an optional validation context so applications can provide translation or failure-formatting hooks:

RegisterRoutes(app, {
  validation: {
    translate: (key, params) => translateMessage(key, params),
    errorFormatter: failure => failure,
  },
})
import * as t from 'io-ts'
import { withMessage } from 'io-ts-types'
import { Body, Controller, Post, Route, Validate } from 'tsoa-next'

interface PositiveFloatBrand {
  readonly PositiveFloat: unique symbol
}

const PositiveFloat = withMessage(
  t.brand(t.number, (n): n is t.Branded<number, PositiveFloatBrand> => Number.isFinite(n) && n > 0, 'PositiveFloat'),
  () => 'validation.wager.amount.mustBePositiveFloat',
)

const WagerCodec = t.type({
  amount: PositiveFloat,
  outcome: t.Int,
})

type Wager = t.TypeOf<typeof WagerCodec>

@Route('wagers')
export class WagersController extends Controller {
  @Post()
  public createWager(
    @Body()
    @Validate('io-ts', WagerCodec)
    wager: Wager,
  ): Wager {
    return wager
  }
}

Migration Note

This feature is fully opt-in. If you do not use @Validate(...), existing interface/class models, generated routes, validation behavior, and error responses are unchanged.

Getting Started

Package Surface

  • Import decorators, runtime helpers, and generated route support from tsoa-next
  • Import programmatic generation APIs from tsoa-next/cli
  • Use the tsoa binary for CLI generation commands

Examples

Check out the guides

See example controllers in the tests

See example models in the tests

Help wanted

Contributing code

To contribute (via a PR), please first see the Contributing Guide

Release History

VersionChangesUrgencyDate
tsoa-next@8.2.2### Patch Changes - 5d3e303: Fixed generated `@SpecPath(...)` routes so they register before regular controller routes in the Express, Koa, and Hapi templates. This prevents dynamic first-segment routes such as `/{tenant}/{resource}` from shadowing spec endpoints like `/SpecPath/spec`. Refreshed the docs site and API reference to ship from one VitePress pipeline with `typedoc-plugin-markdown`, grouped install snippets, generated `llms.txt` output, published changelog pages, syntax-highliHigh4/17/2026
tsoa-next@8.2.0### Minor Changes - 8a8ff5b: Improve `@SpecPath(...)` support by adding the `@SpecPath(path, options?)` signature with `target`, `cache`, and request-aware `gate` controls. Generated Express, Koa, and Hapi routes now omit `SpecPath` support when no controller uses the decorator, and statically gated spec routes are skipped during registration. ### Patch Changes - Updated dependencies [8a8ff5b] - @tsoa-next/cli@8.2.0 - @tsoa-next/runtime@8.2.0 High4/14/2026
tsoa-next@8.1.0### Minor Changes - 84bb4a6: Add repeatable `@SpecPath(...)` controller decorators for serving OpenAPI documents and documentation UIs directly from generated routes without reading a local spec file at request time. This release adds: - Built-in `json`, `yaml`, `swagger`, `redoc`, and `rapidoc` `@SpecPath(...)` targets - Lazy in-memory spec generation for built-in spec routes through `createOpenApiSpecGenerator(...)` - Support for multiple `@SpecPath(...)` decorators High4/12/2026
tsoa-next@8.0.4### Patch Changes - 9fdb94a: Fixed inherited route detection for derived controllers whose base class imports `Controller` from `tsoa-next`. - 464a0c7: Fixed metadata generation for inherited generic controller routes and `io-ts` request aliases used in real-world controller setups. Also reduced repeated CLI generation work while resolving inherited methods and imported validator types. - Updated dependencies [9fdb94a] - Updated dependencies [464a0c7] - @tsoa-next/cli@8.0.4 - High4/9/2026
@tsoa-next/runtime@8.0.2### Patch Changes - 63e57e3: Remediate the Sonar cleanup pass across the CLI and runtime without changing the public API surface. This patch keeps the existing exported contracts intact while reducing internal complexity, preserving legacy compatibility paths, and tightening integration and unit assertions around the affected behavior. High4/4/2026

Dependencies & License Audit

Loading dependencies...

Similar Packages

in-concertFull, scalable BPMN 2.0 enginemain@2026-04-19
CoalesceQuickly build amazing web apps6.4.0
aiagentflowA local-first, CLI-driven multi-agent AI software engineering workflow orchestrator with feed specs, PRDs, and guidelines to auto-generate implementation plans and code.v1.0.2
typesharpTypeSharp CLI - Automatically generate TypeScript from C# models. Keep your frontend and backend types in perfect sync! Supports nullable types, enums, inheritance, arrays, and custom naming conventiov0.2.0
risolutoAI-powered orchestrator that turns Linear issues into working code โ€” autonomous coding agents, real-time dashboard, and seamless GitHub integrationv0.9.0