Getting Started
Getting Started
Section titled “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/cjswas parsed as ESM, because the rootpackage.jsondeclares"type": "module"- runtime dependencies were bundled into
dist, shipping a duplicate copy of Zod — which broke identity checks against schemas you created — and manglingsemverinto 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 scaffolding —
veloce generate controller/service/module/resolver/dto/middleware/plugin <name>generates typed boilerplate instantly - Graceful shutdown —
app.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)onAsyncGeneratorhandlers for SSE and CSV exports - Event bus —
EventBusandglobalEventssingleton for in-process pub/sub without Redis - Extra decorators —
@Throttle,@ApiVersion,@ResponseHeader,@Redirect,@Deprecated - Test isolation —
isolate()andcompileTestApp()for flake-free parallel tests - OpenAPI 3.1 —
jsonSchemaDialect,nullable→type: ['x','null']:::
:::tip What’s New in v1.0.1
- GraphQL decorator pipeline fixed —
@Resolver,@GQLQuery,@GQLMutation, and@Argwork end-to-end. Pass resolver classes viaresolvers: [...]on the plugin orapp.include(). PermissionManager.revokePermission()fixed — permissions are now removed correctly when noresourceIdis 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,@Deprecatedfor 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
TestResponsewith chainable assertions (expectOk(),expectJson(),expectField()) - Drizzle ORM DI integration —
registerDrizzle()and@InjectDB()for clean database injection - 6 new HTTP exception classes —
ConflictException,GoneException,PayloadTooLargeException,UnprocessableEntityException,TooManyRequestsException,ServiceUnavailableException - Auto-tagging and Bearer security in OpenAPI generator
- Improved validation error shape — structured
field,received,expected,minimum/maximumin 422 responses :::
Installation
Section titled “Installation”Install Veloce using your preferred package manager:
# Using Bun (recommended)bun add veloce-ts zod
# Using npmnpm install veloce-ts zod
# Using pnpmpnpm add veloce-ts zodQuick Start
Section titled “Quick Start”Create your first API in minutes:
import { Veloce, Controller, Get, Post, Body } from 'veloce-ts';import { z } from 'zod';
// Define schemasconst 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 appconst app = new Veloce();app.include(UserController);app.listen(3000);
console.log('Server running on http://localhost:3000');TypeScript Configuration
Section titled “TypeScript Configuration”Add these settings to your tsconfig.json:
{ "compilerOptions": { "experimentalDecorators": true, "emitDecoratorMetadata": true, "target": "ES2022", "module": "ESNext", "moduleResolution": "bundler" }}Project Structure
Section titled “Project Structure”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.jsonUsing the CLI
Section titled “Using the CLI”Veloce-TS includes a powerful CLI tool for project creation and code generation:
# Create a new projectveloce new my-api
# Generate a full module (controller + service + DTO + barrel)veloce generate module users
# Generate individual piecesveloce generate controller productsveloce generate service productsveloce generate dto create-productveloce generate resolver userveloce generate middleware authveloce generate plugin analyticsSee the CLI guide for all options.
Next Steps
Section titled “Next Steps”- CLI guide — code generation reference
- Exception Filters — centralized error handling
- Interceptors — AOP logging and caching
- Streaming — SSE and streaming responses
- Event Bus — in-process pub/sub
- Decorators — full decorator reference
- Dependency Injection
- Plugins
- API Reference