Skip to content

Getting Started

Welcome to Veloce-TS! This guide will help you get up and running quickly with the latest features and improvements.

:::danger Upgrading from v1.x? Two breaking changes 1. JWTProvider verification and revocation methods are now async (verifyAccessToken, verifyRefreshToken, refreshAccessToken, blacklistToken, isBlacklisted, cleanupBlacklist). A missing await is worse than a type error here — the returned Promise is always truthy, so a stale if (verifyAccessToken(token)) check now passes for any string. See Authentication.

2. Decorator controllers now default to singleton scope, not a new instance per request. Per-request state kept in instance fields is now shared across concurrent requests. Opt out with @Controller('/x', { scope: 'transient' }).

Full diff: MIGRATION.md. :::

:::tip What’s New in v2.0.0 If you deploy on Node.js, upgrade. The published v1.2.0 was genuinely broken there — four separate packaging bugs, all fixed:

  • veloce-ts/adapters/* resolved to a path the build never emitted, so that subpath import failed outright
  • the ESM bundle emitted import.meta.require, a Bun-only global that throws under Node
  • dist/cjs was parsed as ESM, because the root package.json declares "type": "module"
  • runtime dependencies were bundled into dist, shipping a duplicate copy of Zod — which broke identity checks against schemas you created — and mangling semver into an invalid RegExp that threw on require

Security — a refresh token could be replayed as an access token; asymmetric RS256/384/512 silently signed with the shared HMAC secret; rate limiting trusted client-supplied X-Forwarded-For (now opt-in via trustProxy); @ResponseSchema failures were swallowed instead of reported.

Performance — request dispatch is 1.9–2.6× faster. Veloce-TS now beats raw Hono on JSON body parsing (+16.7%) and Zod validation (+43.8%), while still costing ~33% on a trivial route with no body or params to process. Published package dropped from 3.82 MB to 1.33 MB.

GraphQL actually works now. Resolvers were wired to a shape graphql-js never reads, so every query returned null, and every field was typed String. Object and input types are now derived from your Zod schemas.

New APIs — typed functional routes (handler args infer from the Zod schema bag), @Controller(prefix, { scope }), RedisTokenBlacklist for revocation across replicas, Plugin.onStart/onStop lifecycle hooks, app.getFetchHandler() for Cloudflare Workers, WebSocket heartbeat/idle/max-message-size limits, and CacheManager.destroy().

Tooling — the CLI runs under plain Node (it previously required Bun), CI gained a real multi-runtime matrix, and .d.ts build failures are now fatal in production builds. :::

:::tip What’s New in v1.2.0

  • CLI scaffoldingveloce generate controller/service/module/resolver/dto/middleware/plugin <name> generates typed boilerplate instantly
  • Graceful shutdownapp.onShutdown(handler) + automatic SIGTERM/SIGINT handling; configurable timeout
  • Exception filters@Catch(ErrorClass) + app.useFilter() for centralized, typed error responses
  • Interceptors@UseInterceptor() + app.useInterceptor() for AOP logging, caching, and transforms
  • Streaming@SSE() and @Stream(contentType) on AsyncGenerator handlers for SSE and CSV exports
  • Event busEventBus and globalEvents singleton for in-process pub/sub without Redis
  • Extra decorators@Throttle, @ApiVersion, @ResponseHeader, @Redirect, @Deprecated
  • Test isolationisolate() and compileTestApp() for flake-free parallel tests
  • OpenAPI 3.1jsonSchemaDialect, nullabletype: ['x','null'] :::

:::tip What’s New in v1.0.1

  • GraphQL decorator pipeline fixed@Resolver, @GQLQuery, @GQLMutation, and @Arg work end-to-end. Pass resolver classes via resolvers: [...] on the plugin or app.include().
  • PermissionManager.revokePermission() fixed — permissions are now removed correctly when no resourceId is specified.
  • 509 tests — 89 new tests covering PermissionPlugin, HealthCheckPlugin, Logger, OAuthPlugin, and GraphQL. :::

:::tip What’s New in v0.4.0

  • New OpenAPI shorthand decorators@Summary, @Description, @Tag, @Tags, @Deprecated for concise route documentation
  • Response control decorators@HttpCode(statusCode) and @ResponseSchema(schema) to control and document responses
  • Per-route middleware decorators@Timeout(ms) and @RateLimit(options) applied declaratively
  • Fluent TestClient — new TestResponse with chainable assertions (expectOk(), expectJson(), expectField())
  • Drizzle ORM DI integrationregisterDrizzle() and @InjectDB() for clean database injection
  • 6 new HTTP exception classesConflictException, GoneException, PayloadTooLargeException, UnprocessableEntityException, TooManyRequestsException, ServiceUnavailableException
  • Auto-tagging and Bearer security in OpenAPI generator
  • Improved validation error shape — structured field, received, expected, minimum/maximum in 422 responses :::

Install Veloce using your preferred package manager:

Terminal window
# Using Bun (recommended)
bun add veloce-ts zod
# Using npm
npm install veloce-ts zod
# Using pnpm
pnpm add veloce-ts zod

Create your first API in minutes:

import { Veloce, Controller, Get, Post, Body } from 'veloce-ts';
import { z } from 'zod';
// Define schemas
const UserSchema = z.object({
name: z.string().min(2),
email: z.string().email(),
});
// Create a controller
@Controller('/users')
class UserController {
@Get('/')
async getUsers() {
return [
{ id: 1, name: 'John Doe', email: 'john@example.com' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com' },
];
}
@Post('/')
async createUser(@Body(UserSchema) user: z.infer<typeof UserSchema>) {
return { id: 3, ...user };
}
}
// Create and start the app
const app = new Veloce();
app.include(UserController);
app.listen(3000);
console.log('Server running on http://localhost:3000');

Add these settings to your tsconfig.json:

{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES2022",
"module": "ESNext",
"moduleResolution": "bundler"
}
}

A typical Veloce-TS project structure:

my-api/
├── src/
│ ├── controllers/
│ │ └── user.controller.ts
│ ├── services/
│ │ └── user.service.ts
│ ├── schemas/
│ │ └── user.schema.ts
│ └── index.ts
├── package.json
└── tsconfig.json

Veloce-TS includes a powerful CLI tool for project creation and code generation:

Terminal window
# Create a new project
veloce new my-api
# Generate a full module (controller + service + DTO + barrel)
veloce generate module users
# Generate individual pieces
veloce generate controller products
veloce generate service products
veloce generate dto create-product
veloce generate resolver user
veloce generate middleware auth
veloce generate plugin analytics

See the CLI guide for all options.