Core Features
A clean API, powerful type inference and built-in validation, designed for productive development
Blazing Fast
1.8x faster than Express
JIT-compiled validators · Radix tree router
Type Safe
End-to-end type inference
Schema → Type · Cross-file types
Declarative Routing
Structure is the truth
Routes are arrays · Explicit middleware
Cross-Runtime
One codebase, any environment
Node.js · Bun · Cloudflare Workers
faster than Express
requests/sec
- ElysiaBun~118K
- VafastBun~101K
- HonoBun~56K
- ExpressNode~56K
Test environment: Bun 1.2.20, macOS, wrk (4 threads, 100 connections, 30s)
Made for Developers
An intuitive API with almost no learning curve. No complex abstractions: the code you write is exactly what runs.
import { Server, defineRoute, defineRoutes } from 'vafast'
const routes = defineRoutes([
defineRoute({
method: 'GET',
path: '/',
handler: () => 'Hello World'
}),
defineRoute({
method: 'GET',
path: '/json',
handler: () => ({ message: 'Hello World' })
})
])
const server = new Server(routes)
export default { fetch: server.fetch }Automatic Responses
Return an object and it becomes JSON; return a string and Content-Type is set for you
Semantic Errors
Built-in helpers like err.notFound() with a unified error response format
Declarative Routing
Routes are just arrays, so every endpoint is visible at a glance
Cross-Runtime
The same code runs on Node.js, Bun and Workers
Typed from request to response
Types That Sync Automatically
Define your endpoints on the server and the client gets full type hints automatically: no handwritten types, no code generation.
import { Server, defineRoute, defineRoutes, Type, err } from 'vafast'
const routes = defineRoutes([
defineRoute({
method: 'PATCH',
path: '/profile',
schema: { body: Type.Object({ age: Type.Number() }) },
handler: ({ body }) => {
if (body.age < 18)
throw err.badRequest('Too young')
return { success: true, data: body }
}
})
])
const server = new Server(routes)
// Export the type for the client
export type AppRoutes = typeof routesimport { eden, createClient, type InferEden } from '@vafast/api-client'
import { defineRoute, defineRoutes, Type } from 'vafast'
// Define and handle routes
const routes = defineRoutes([
defineRoute({
method: 'PATCH',
path: '/profile',
schema: { body: Type.Object({ age: Type.Number() }) },
handler: ({ body }) => ({ success: true, data: body })
})
])
// ✅ Type inference just works, no `as const` needed!
type Api = InferEden<typeof routes>
const api = eden<Api>(createClient('https://api.example.com'))
// Full type hints + autocompletion
const { data } = await api.profile.patch({
age: 21
})Catch Errors Early
import { eden, createClient, type InferEden } from '@vafast/api-client'
import { defineRoute, defineRoutes, Type } from 'vafast'
// Define and handle routes
const routes = defineRoutes([
defineRoute({
method: 'PUT',
path: '/user',
schema: { body: Type.Object({ username: Type.String(), password: Type.String() }) },
handler: ({ body }) => ({ success: true, message: 'User created' })
})
])
// ✅ Type inference just works
type Api = InferEden<typeof routes>
const api = eden<Api>(createClient('http://localhost:3000'))
// ❌ Missing password field → compile-time error
const { data } = await api.user.put({ username: 'mika'
})Write Once, Run Anywhere
Built on the standard Web Fetch API and not tied to any runtime. The same code deploys to Node.js, Bun, Cloudflare Workers and more.
Made Possible by You
Vafast isn't owned by any organization; it's driven by the community. Your support keeps Vafast growing.
Thank you for making Vafast possible
Ready to Start?
Set up your first Vafast project in minutes and experience productive API development