Define your NestJS DTOs and Swagger schemas using Arktype
npm install nestjs-arktypenestjs-arktype is a simple library to help you define and validate all your NestJS DTOs using ArkType
- Create your DTOs using ArkType and re-use them anywhere in your app
- Auto validation of your input body / params / query with ArkValidationPipe
- Generate a fully featured OpenAPI spec out of your DTOs with automatic Swagger decorators
- Support for complex nested objects, arrays, and polymorphic types
- Support for string literals and enumerations
``typescript
// user.dto.ts
import { type } from 'arktype';
import { createArkDto } from 'nestjs-arktype';
const userDto = type({
id: 'number.integer',
email: 'string.email',
points: 'number',
firstName: 'string',
lastName: 'string',
});
const createUserBody = type({
email: 'string.email',
firstName: 'string',
lastName: 'string',
});
export class CreateUserBodyDto extends createArkDto(createUserBody, { name: 'CreateUserBodyDto', input: true }) {}
export class UserDto extends createArkDto(userDto, { name: 'UserDto' }) {}
// user.controller.ts
import { Body, Controller, Post } from '@nestjs/common';
import { ApiBody } from '@nestjs/swagger';
@Controller()
export class UserController {
@Post('/user')
@ApiBody({ type: CreateUserBodyDto })
async createUser(@Body() body: CreateUserBodyDto): Promise
const user = this.service.createUser(body);
return UserDto.parse(user); // Validate your output against the schema if you need to
}
}
`
- arktype >= 2.1@nestjs/common
- >= 11@nestjs/swagger
- >= 11
- Node.js 22.x or later
> Important: NestJS doesn't support importing ESM only libraries. ArkType 2 is now ESM only.
> Fortunately Node.js 22 lets you require() ESM modules out of the box, so Node.js 22+ is a hard requirement.
`bash`
npm install nestjs-arktype arktype @nestjs/swagger
`typescript`
export class MyDto extends createArkDto(schema, { name: 'MyDto', input: true })
| Option | Type | Description |
| :-------- | :------- | :------------------------- |
| schema | Type | Required. Any ArkType schema representing your DTO |name
| | string | Required. The name of your DTO (used for OpenAPI generation) |input
| | boolean | Whether the DTO should represent the input schema or output schema (useful for DTOs with defaults) |
Generated DTOs provide static methods for parsing:
`typescript
// Parse and validate data (throws on error)
const validatedData = MyDto.parse(inputData);
// Parse with error reporting only (logs errors instead of throwing)
const result = MyDto.parse(inputData, { reportOnly: true });
`
The validation pipe uses your ArkType schemas to parse and validate incoming data
from your parameter decorators. When the data is not valid, it throws a
BadRequestException with a detailed summary of what went wrong.
To use it, in your main app.module add the validation pipe:
`typescript
import { Module } from '@nestjs/common';
import { APP_PIPE } from '@nestjs/core';
import { ArkValidationPipe } from 'nestjs-arktype';
@Module({
providers: [
{
provide: APP_PIPE,
useClass: ArkValidationPipe,
},
],
})
export class AppModule {}
`
Now whenever you use a parameter decorator in your controllers, it will be
automatically parsed through the ArkType schema if the DTO is an ArkTypeDto.
`typescript``
async createUser(@Body() body: CreateUserBodyDto) {
return body; // Body is parsed and validated with the ArkType schema
}
- nestjs-zod - For inspiration and solutions