docfy export
Boots the project's own Nest app and writes the OpenAPI document, without binding a port or needing live infrastructure.
Why it exists
The one thing SwaggerModule.createDocument() structurally needs is a fully-initialized Nest app: its DI container has to resolve every provider before route and DTO metadata exists to introspect.
That does not require .listen(). No port gets bound.
In practice it usually doesn't need live infrastructure either: most TypeOrmModule, ioredis, and kafkajs clients connect lazily rather than blocking bootstrap, so export tends to work with the database, Redis, and Kafka all stopped.
Usage
Provide a small entry file (the same lines your main.ts already has, minus .listen()):
// docfy-export.ts
import { NestFactory } from '@nestjs/core';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
export default async function () {
const app = await NestFactory.create(AppModule, { logger: false });
const config = new DocumentBuilder().setTitle('My API').setVersion('1.0.0').build();
const document = SwaggerModule.createDocument(app, config);
return { app, document }; // `app` gets closed for you afterward
}npx nestjs-docfy export --entry docfy-export.ts --out openapi.jsonInformational output always goes to stderr, never stdout, so it's safe to pipe: npx nestjs-docfy export --entry docfy-export.ts > openapi.json.
The entry file contract
The default export is an async function returning { app, document }. export runs it in a spawned child process, serializes document, and calls app.close() for you afterward.
A .ts entry needs ts-node as a devDependency of your project (and tsconfig-paths too, for path aliases like @app/common).
Options
| Option | Default | Description |
|---|---|---|
--entry <path> | (required) | .ts/.js file whose default export returns { app, document } |
--out <path> | stdout | Where to write the document |
--root <path> | . | Project root — where ts-node/tsconfig-paths are resolved from |
--quiet | false | Suppress informational output |
A provider with a genuinely eager, hard-failing connection in its constructor or onModuleInit won't benefit from skipping infra this way. Nothing in export can change how your own providers connect. It only avoids the one thing NestJS itself doesn't need: an open port.