tsgonest vs Nestia + Typia
Architecture and DX comparison between tsgonest and the Nestia/Typia ecosystem.
Nestia and Typia are TypeScript libraries by Samchon that take a similar "types as source of truth" approach to validation and serialization. This page compares tsgonest with the Nestia + Typia stack.
At a glance
| Feature | Nestia + Typia | tsgonest |
|---|---|---|
| Compilation | tsc with ts-patch transform plugin | tsgo (~10x raw compilation, ~4x full pipeline) |
| Validation | typia.assert<T>() calls | Compile-time injection |
| Serialization | typia.json.stringify<T>() calls | Compile-time injection |
| OpenAPI | @nestia/swagger (runtime analysis) | Static analysis at build time |
| NestJS integration | @nestia/core custom decorators | Standard NestJS decorators |
| Setup | ts-patch + tsconfig plugin config | Single CLI binary |
| Branded types | typia.tags.Format<"email"> etc. | @tsgonest/types Email, Min, Max, etc. |
| Watch mode | External (nodemon, ts-node-dev) | Built-in tsgonest dev |
Architecture difference
Typia: compiler plugin
Typia works as a TypeScript compiler plugin via ts-patch. It transforms typia.assert<T>(input) calls into inline validation code during compilation. The validation code is inlined at each call site — there is no separate companion file.
tsgonest: companion files
tsgonest analyzes your project's types and generates companion files alongside the compiled output. These are imported automatically — tsgonest's controller rewriter injects the correct import and function calls into the compiled controller JS at build time. Your source code doesn't need to reference them directly.
What this means in practice
| Aspect | Typia (plugin) | tsgonest (codegen) |
|---|---|---|
| Explicit calls needed | Yes — typia.assert<T>() at every use site | No — injected at compile time |
| Bundle size impact | Inline code at every call site | Single companion per type |
| NestJS integration | @nestia/core decorators replace NestJS ones | Zero-config, keep standard decorators |
| Build tooling | Requires ts-patch, plugin config in tsconfig | Single tsgonest build command |
| Build speed | tsc speed (with plugin overhead) | tsgo speed (~4x faster) |
DX comparison
Defining DTOs
Both approaches let you use plain TypeScript types. The branded type syntax differs slightly:
// Typia
import typia, { tags } from 'typia';
interface CreateUserDto {
name: string & tags.MinLength<1> & tags.MaxLength<255>;
email: string & tags.Format<"email">;
age: number & tags.Minimum<0> & tags.Maximum<150>;
}// tsgonest
import { Min, Max, Email } from '@tsgonest/types';
interface CreateUserDto {
name: string & Min<1> & Max<255>;
email: string & Email;
age: number & Min<0> & Max<150>;
}tsgonest offers shorter aliases (Min vs Minimum, Email vs Format<"email">) and compound types like Range, Between, and Length.
tsgonest also recognizes typia's "typia.tag" branded type convention. If you're migrating from typia, your existing branded types will be detected automatically.
Validation
// Typia — explicit calls required
import typia from 'typia';
@Controller('users')
export class UserController {
@Post()
create(@Body() input: CreateUserDto) {
const dto = typia.assert<CreateUserDto>(input); // must call explicitly
return this.userService.create(dto);
}
}// tsgonest — automatic, no explicit calls needed
@Controller('users')
export class UserController {
@Post()
create(@Body() dto: CreateUserDto) {
return this.userService.create(dto);
}
}With tsgonest, validation is injected at compile time — no pipes, no runtime setup, no explicit calls.
Nestia vs standard NestJS decorators
Nestia replaces NestJS's standard decorators with its own:
// Nestia — custom decorators
import { TypedBody, TypedRoute } from '@nestia/core';
@Controller('users')
export class UserController {
@TypedRoute.Post()
create(@TypedBody() dto: CreateUserDto): UserResponse {
return this.userService.create(dto);
}
}// tsgonest — standard NestJS decorators
import { Controller, Post, Body } from '@nestjs/common';
@Controller('users')
export class UserController {
@Post()
create(@Body() dto: CreateUserDto): UserResponse {
return this.userService.create(dto);
}
}tsgonest works with standard NestJS decorators — no migration to a different API.
OpenAPI generation
Nestia
Nestia generates OpenAPI at runtime — it requires booting the NestJS application and using Nestia-specific decorators.
tsgonest
tsgonest generates OpenAPI at build time via static analysis:
import { defineConfig } from '@tsgonest/runtime';
export default defineConfig({
openapi: {
output: 'dist/openapi.json',
title: 'My API',
version: '1.0.0',
},
});No application boot. No runtime cost. Standard NestJS decorators.
Setup comparison
Typia + Nestia
npm install typia @nestia/core @nestia/sdk
npx ts-patch install{
"compilerOptions": {
"plugins": [
{ "transform": "typia/lib/transform" },
{ "transform": "@nestia/core/lib/transform" }
]
}
}Requires ts-patch, plugin entries in tsconfig.json, and can conflict with other TypeScript tooling (SWC, esbuild).
tsgonest
npm install tsgonestimport { defineConfig } from '@tsgonest/runtime';
export default defineConfig({
controllers: { include: ['src/**/*.controller.ts'] },
transforms: { validation: true, serialization: true },
openapi: { output: 'dist/openapi.json' },
});No patches. No plugins. No tsconfig modifications.
Feature comparison table
| Feature | Typia | Nestia | tsgonest |
|---|---|---|---|
| Validation | typia.assert<T>() | Via @TypedBody() | Compile-time injection |
| Serialization | typia.json.stringify<T>() | Via @TypedRoute | Compile-time injection |
| OpenAPI | N/A | @nestia/sdk (runtime) | Static analysis (build time) |
| Interfaces support | Yes | Yes | Yes |
| Type aliases support | Yes | Yes | Yes |
| Custom validators | typia.customValidators | Via typia | Validate<typeof fn> |
| Branded types | typia.tags.* | Via typia tags | @tsgonest/types |
| Transforms (trim, etc.) | Not built-in | Not built-in | Trim, ToLowerCase, ToUpperCase |
| Coercion | Not built-in | Not built-in | Coerce type tag |
| Default values | Not built-in | Not built-in | Default<V> type tag |
| Per-constraint errors | Not supported | Not supported | Min<{ value: 0, error: "..." }> |
| Watch mode | External tooling | External tooling | Built-in tsgonest dev |
| Build speed | tsc speed | tsc speed | ~4x faster (tsgo) |
| NestJS decorators | Replaced by Nestia | Custom decorators | Standard NestJS decorators |
| Multipart/form-data | N/A | @TypedFormData.Body() | @FormDataBody() + FormDataInterceptor |
| Compiler requirement | ts-patch | ts-patch | None (standalone binary) |
Migration from Nestia + Typia
The fastest way to migrate is with the automated codemod:
npx tsgonest migrate --applyThis handles decorator replacement, import rewrites, dependency cleanup, and tsconfig fixes automatically. See the generated tsgonest-migrate-report.md for a summary of all changes.
For manual migration details, see the Migration from Nestia + Typia guide.