Más que solo
documentación Swagger.

nestjs-docfy separa la documentación Swagger/OpenAPI de la lógica del controller usando una convención de nombres de archivo companion, de la misma forma en que Nest ya lo hace con *.controller.spec.ts.

Installation
npm install nestjs-docfy
# peer deps
npm install @nestjs/common @nestjs/swagger reflect-metadata
Última versión v0.13.0Licencia MIT
Archivo companion por convención
users.controller.ts → users.controller.docs.ts. El mismo patrón que Nest ya usa para *.controller.spec.ts.
CLI con gates de CI
check, coverage --min, lint y patch-spec. Falla el build cuando falta documentación.
Inferencia de tipos automática
Interfaces, class-validator y @HttpCode() se convierten en un schema OpenAPI sin decorators extra.
Docfy UI AI-first
Una UI de referencia con un botón Copy for AI en cada endpoint, ideal para pegar en LLMs.

docfy-ui: un visor de referencia AI-first

La spec OpenAPI que ensambla nestjs-docfy es también lo que renderiza docfy-ui, sin configuración aparte y con la misma fuente de verdad.

  • Copy for AI: un resumen determinista del endpoint, listo para LLM, no un volcado de JSON crudo con $ref
  • Búsqueda con ⌘K en todos los endpoints, al instante
  • Detalle completo de request/response por endpoint, generado directamente desde la spec
docfy-ui overview
docfy-ui busca com ⌘K
docfy-ui detalhe de endpoint com Copy for AI

Cómo se ve en la práctica

Antes: un controller enterrado en decorators. Después: solo rutas, con la documentación viviendo al lado, en un archivo companion.

users.controller.ts
@WithDocs()
@Controller('users')
export class UsersController {
  constructor(private readonly users: UsersService) {}

  @Get(':id')
  findOne(@Param('id') id: string) {
    return this.users.findOne(id);
  }
}
users.controller.docs.ts
import { docs } from 'nestjs-docfy';
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';
import { UsersController } from './users.controller';

docs(UsersController, {
  classDecorators: [ApiTags('users')],
  methods: {
    findOne: [
      ApiOperation({ summary: 'Get user by id' }),
      ApiResponse({ status: 200, description: 'OK', type: UserDto }),
      ApiResponse({ status: 404, description: 'User not found' }),
    ],
  },
});
Solo en boot-time, cero overhead por requestMisma salida OpenAPI que decorators inlineConvención de archivo companion, como *.spec.ts

Sin monkey-patching, sin proxies en runtime

Solo el timing correcto y metadata de Reflect.

01

Escribe el archivo companion

users.controller.docs.ts llama a docs(UsersController, { ... }), decorators de Swagger normales, solo que en otro archivo.

02

Descubierto al arrancar

DocfyModule.forRoot() lo encuentra vía la convención de nombres y escribe metadata de Reflect en los métodos del controller, antes de que se ejecute SwaggerModule.createDocument().

03

Salida OpenAPI idéntica

SwaggerModule ve exactamente la misma metadata que vería si los decorators estuvieran escritos inline en el controller.