Skip to main content
tsoa is configured through a configuration file that defines how specifications and routes are generated. The configuration file can be in JSON, YAML, or JavaScript format.

Configuration File

By default, tsoa looks for tsoa.json in your project root. You can use alternative formats or locations:
{
  "entryFile": "src/app.ts",
  "noImplicitAdditionalProperties": "throw-on-extras",
  "spec": {
    "outputDirectory": "dist",
    "specVersion": 3
  },
  "routes": {
    "routesDir": "src",
    "middleware": "express"
  }
}
Use JavaScript format (tsoa.js) when you need dynamic configuration or want to compute values at runtime.

Configuration Structure

The configuration file has four main sections:
interface Config {
  entryFile: string;                    // Entry point to your API
  spec: SpecConfig;                     // OpenAPI spec generation
  routes: RoutesConfig;                 // Route handler generation
  // Optional settings
  controllerPathGlobs?: string[];       // Alternative to entryFile
  noImplicitAdditionalProperties?: string;
  compilerOptions?: Record<string, unknown>;
  ignore?: string[];
  multerOpts?: MulterOptions;
  defaultNumberType?: string;
}

Entry Point Configuration

You must specify how tsoa finds your controllers using either entryFile or controllerPathGlobs:

Using entryFile

Points to a file that imports all your controllers:
{
  "entryFile": "src/app.ts"
}
src/app.ts
import './controllers/usersController';
import './controllers/productsController';
import './controllers/ordersController';
// tsoa will scan all imported controllers
The entry file doesn’t need to contain any tsoa-specific code. It just needs to import your controllers directly or indirectly.

Using controllerPathGlobs

Use glob patterns to directly specify controller files:
{
  "controllerPathGlobs": [
    "src/controllers/**/*Controller.ts",
    "src/modules/**/controllers/*.ts"
  ]
}

entryFile

Pros:
  • Single source of truth
  • Respects your imports
  • Works with any structure
Cons:
  • Must import all controllers
  • Slower for large projects

controllerPathGlobs

Pros:
  • Faster generation
  • No import required
  • Explicit file selection
Cons:
  • Must maintain glob patterns
  • Could pick up unwanted files

Global Options

noImplicitAdditionalProperties

Controls how tsoa handles extra properties in request bodies:
noImplicitAdditionalProperties
enum
{
  "noImplicitAdditionalProperties": "throw-on-extras"
}
interface CreateUserRequest {
  name: string;
  email: string;
}

@Post('users')
public async createUser(@Body() body: CreateUserRequest) {
  // ...
}
Using "throw-on-extras" provides the strictest validation but may break clients sending additional fields. Start with "silently-remove-extras" for a safer migration path.

ignore

Directories to ignore when scanning TypeScript files:
{
  "ignore": [
    "**/node_modules/**",
    "**/test/**",
    "**/dist/**"
  ]
}
Ignoring unnecessary directories significantly improves generation speed for large projects.

compilerOptions

Override TypeScript compiler options during generation:
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "commonjs",
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}
These options are merged with your tsconfig.json. Use this when generation needs different settings than your build.

defaultNumberType

How TypeScript number type maps to OpenAPI:
{
  "defaultNumberType": "double"
}
defaultNumberType
enum
default:"double"
  • "double" - 64-bit floating point
  • "float" - 32-bit floating point
  • "integer" - 32-bit integer
  • "long" - 64-bit integer
interface Product {
  price: number;        // Uses defaultNumberType
  quantity: number;     // Uses defaultNumberType
  
  // Override with JSDoc tags:
  /** @isInt */
  stock: number;        // Always integer
  
  /** @isFloat */
  rating: number;       // Always float
}

Spec Configuration

Controls OpenAPI specification generation:
{
  "spec": {
    "outputDirectory": "dist",
    "specVersion": 3,
    "specFileBaseName": "swagger",
    "host": "api.example.com",
    "basePath": "/v1",
    "schemes": ["https"],
    "yaml": true
  }
}

Required Options

spec.outputDirectory
string
required
Directory where the OpenAPI spec file will be written.
{ "spec": { "outputDirectory": "dist/docs" } }

Version and Format

spec.specVersion
number
default:2
OpenAPI version to generate: 2, 3, or 3.1
{ "spec": { "specVersion": 3 } }
spec.yaml
boolean
default:false
Output in YAML format instead of JSON.
{ "spec": { "yaml": true } }
spec.specFileBaseName
string
default:"swagger"
Base name of the output file (without extension).
{ "spec": { "specFileBaseName": "openapi" } }
Generates openapi.json or openapi.yaml

API Information

By default, tsoa extracts these from package.json:
spec.name
string
API name (defaults to package.json name)
spec.version
string
API version (defaults to package.json version)
spec.description
string
API description (defaults to package.json description)
spec.license
string
API license (defaults to package.json license)
{
  "spec": {
    "name": "My API",
    "version": "2.0.0",
    "description": "A comprehensive API for...",
    "license": "MIT"
  }
}

Server Configuration

{
  "spec": {
    "specVersion": 2,
    "host": "api.example.com",
    "basePath": "/v1",
    "schemes": ["https", "http"]
  }
}
Generates URLs like: https://api.example.com/v1/users

Advanced Spec Options

See the tsoa.json Reference for complete details on:
  • Security definitions
  • Contact information
  • Tags
  • Spec merging strategies
  • Operation ID templates
  • And more…

Routes Configuration

Controls route handler generation:
{
  "routes": {
    "routesDir": "src",
    "middleware": "express",
    "routesFileName": "routes.ts",
    "basePath": "/api",
    "authenticationModule": "./auth.ts",
    "iocModule": "./ioc.ts"
  }
}

Required Options

routes.routesDir
string
required
Directory where routes file will be generated.
{ "routes": { "routesDir": "src/generated" } }

Middleware Selection

routes.middleware
enum
Web framework to generate routes for:
  • "express" - Express.js
  • "koa" - Koa.js
  • "hapi" - Hapi.js
{ "routes": { "middleware": "express" } }
import express from 'express';
import { RegisterRoutes } from './routes';

const app = express();
app.use(express.json());

RegisterRoutes(app);

app.listen(3000);

Module Integration

routes.authenticationModule
string
Path to authentication handler module.
{ "routes": { "authenticationModule": "./auth/handler.ts" } }
Authentication module must export an expressAuthentication (or koaAuthentication/hapiAuthentication) function:
auth/handler.ts
import { Request } from 'express';

export function expressAuthentication(
  request: Request,
  securityName: string,
  scopes?: string[]
): Promise<any> {
  if (securityName === 'jwt') {
    const token = request.headers.authorization?.split(' ')[1];
    return verifyJWT(token, scopes);
  }
  throw new Error('Unknown security scheme');
}
routes.iocModule
string
Path to IoC container module (e.g., for InversifyJS).
{ "routes": { "iocModule": "./ioc/container.ts" } }
IoC module must export an iocContainer:
ioc/container.ts
import { Container } from 'inversify';
import { UserService } from './services';

const iocContainer = new Container();
iocContainer.bind<UserService>(UserService).toSelf();

export { iocContainer };

Additional Options

routes.routesFileName
string
default:"routes.ts"
Name of the generated routes file.
routes.basePath
string
default:"/"
Base path prepended to all routes.
routes.esm
boolean
default:false
Generate imports with .js extensions for ES modules.
{ "routes": { "esm": true } }
Generates: import { Controller } from './controller.js'
routes.bodyCoercion
boolean
default:true
Automatically coerce body parameters to expected types.
routes.noWriteIfUnchanged
boolean
default:false
Skip writing routes file if content hasn’t changed (useful for watch mode).

Example Configurations

Basic Express API

tsoa.json
{
  "entryFile": "src/app.ts",
  "noImplicitAdditionalProperties": "silently-remove-extras",
  "spec": {
    "outputDirectory": "dist",
    "specVersion": 3,
    "basePath": "/api"
  },
  "routes": {
    "routesDir": "src",
    "middleware": "express",
    "basePath": "/api"
  }
}

Production API with Security

tsoa.json
{
  "entryFile": "src/server.ts",
  "noImplicitAdditionalProperties": "throw-on-extras",
  "ignore": ["**/node_modules/**", "**/test/**"],
  "spec": {
    "outputDirectory": "docs",
    "specVersion": 3,
    "specFileBaseName": "openapi",
    "servers": ["https://api.example.com"],
    "basePath": "/v1",
    "securityDefinitions": {
      "jwt": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT"
      },
      "api_key": {
        "type": "apiKey",
        "name": "X-API-Key",
        "in": "header"
      }
    }
  },
  "routes": {
    "routesDir": "src/generated",
    "routesFileName": "routes.ts",
    "middleware": "express",
    "basePath": "/v1",
    "authenticationModule": "./auth/authentication.ts"
  }
}

Microservices with Globs

tsoa.json
{
  "controllerPathGlobs": [
    "src/modules/users/controllers/**/*.ts",
    "src/modules/orders/controllers/**/*.ts",
    "src/modules/products/controllers/**/*.ts"
  ],
  "noImplicitAdditionalProperties": "throw-on-extras",
  "spec": {
    "outputDirectory": "api-docs",
    "specVersion": 3.1,
    "yaml": true
  },
  "routes": {
    "routesDir": "src/generated",
    "middleware": "koa",
    "iocModule": "./di/container.ts",
    "authenticationModule": "./middleware/auth.ts"
  }
}

Next Steps

tsoa.json Reference

Complete schema reference with all options

CLI Commands

Learn about CLI commands and flags

Build docs developers (and LLMs) love