Architecture Overview
Every Velox TS application is built from procedures — type-safe functions that define your business logic once and expose it through multiple protocols and frontiers simultaneously. Your architecture is shaped by two independent choices: how clients talk to your API, and how (or whether) you deliver a frontend.
The Core Abstraction: Procedures
Section titled “The Core Abstraction: Procedures”At the heart of Velox TS is the procedure — a type-safe function that can be exposed as both tRPC and REST:
import { resourceSchema, resource } from '@veloxts/router';
// Define resource schema with field visibilityconst UserSchema = resourceSchema() .public('id', z.string()) .public('name', z.string()) .authenticated('email', z.string()) .build();
const getUser = procedure() .input(z.object({ id: z.string() })) .query(async ({ input, ctx }) => { const user = await ctx.db.user.findUniqueOrThrow({ where: { id: input.id } }); return resource(user, UserSchema.public); });This single definition generates:
- tRPC endpoint — Full type inference for TypeScript clients
- REST endpoint —
GET /api/users/:idfor any HTTP client - Context-dependent outputs — Different fields based on user access level
Because the same procedures power every architecture, your choices come down to two questions.
Two Choices, One Procedure Layer
Section titled “Two Choices, One Procedure Layer”API Protocol: tRPC, REST, or Both
Section titled “API Protocol: tRPC, REST, or Both”These options are non-exclusive. A single set of procedures can expose tRPC endpoints, REST endpoints, or both at the same time. You don’t have to pick one — and in fact, serving both protocols from the same procedures is the default.
| Protocol | Best for | Learn more |
|---|---|---|
| tRPC | TypeScript clients, full type inference | tRPC API |
| REST | Non-TS clients, mobile apps, public APIs, OpenAPI | REST API |
| Both | Different consumers with different needs (the default) | Hybrid |
Frontend Delivery: SPA or RSC
Section titled “Frontend Delivery: SPA or RSC”This choice is mutually exclusive — pick one project shape when you scaffold your application.
| Frontend | Project shape | Process model | Learn more |
|---|---|---|---|
| Vite SPA | Monorepo with apps/api + apps/web | Two processes | SPA + Backend |
| RSC (Vinxi) | Single package, file-based routing | One process | Full-stack RSC |
Pick a Template
Section titled “Pick a Template”- Building a backend for a TypeScript SPA? Use
--defaultor--trpc - Building a full web app with SSR? Use
--rscor--rsc-auth - Need authentication? Use
--author--rsc-auth - All your consumers are TypeScript? Use
--trpc - Need OpenAPI docs or non-TS clients? Use
--defaultor--auth
| Template | Frontend | Protocol | Auth | Command |
|---|---|---|---|---|
| Default | Vite SPA | REST (+ tRPC ready) | No | npx create-velox-app my-app |
| Auth | Vite SPA | REST (+ tRPC ready) | JWT | npx create-velox-app my-app --auth |
| tRPC | Vite SPA | tRPC only (+ REST ready) | No | npx create-velox-app my-app --trpc |
| RSC | RSC (Vinxi) | REST (embedded) | No | npx create-velox-app my-app --rsc |
| RSC + Auth | RSC (Vinxi) | REST + auth (embedded) | JWT | npx create-velox-app my-app --rsc-auth |
Technology Stack
Section titled “Technology Stack”| Layer | Technology |
|---|---|
| HTTP Server | Fastify |
| RPC | tRPC |
| Validation | Zod |
| ORM | Prisma |
| Full-stack | Vinxi + React 19 |