Getting Started
This guide walks you through installing Hedystia and creating your first typed server.
Prerequisites
Hedystia requires Bun as its runtime. If you haven't installed it yet:
bash
curl -fsSL https://bun.sh/install | bashInstallation
Create a new project and install the required packages:
bash
mkdir my-api && cd my-api
bun init -y
bun add hedystiaTo use the typed client in a separate project or package:
bash
bun add @hedystia/clientYour First Server
Create an index.ts file:
ts
import Hedystia, { h } from 'hedystia'
const app = new Hedystia()
.get('/', () => ({ message: 'Hello from Hedystia!' }), {
response: h.object({ message: h.string() }),
})
.listen(3000)
console.log('Server running at http://localhost:3000')Run the server:
bash
bun run index.tsVisit http://localhost:3000 — you should see:
Response
{
"message": "Hello from Hedystia!"
}Adding a Route with Params
ts
import Hedystia, { h } from 'hedystia'
const app = new Hedystia()
.get(
'/users/:id',
({ params }) => {
return { id: params.id, name: 'Jane Doe' }
},
{
params: h.object({ id: h.number().coerce() }),
response: h.object({
id: h.number(),
name: h.string(),
}),
}
)
.listen(3000)The h.number().coerce() call tells Hedystia to coerce the URL param (which arrives as a string) into a number before passing it to the handler.
Adding a POST Route
ts
import Hedystia, { h } from 'hedystia'
const app = new Hedystia()
.post(
'/users',
({ body }) => {
return { id: 1, name: body.name, email: body.email }
},
{
body: h.object({
name: h.string(),
email: h.string().email(),
}),
response: h.object({
id: h.number(),
name: h.string(),
email: h.string(),
}),
}
)
.listen(3000)Using the Client
Once your server is running, create a client with full type inference:
ts
import { createClient } from '@hedystia/client'
import type { app } from './server' // import just the type
const client = createClient<typeof app>('http://localhost:3000')
// POST /users
const { data, error } = await client.users.post({
body: { name: 'Alice', email: 'alice@example.com' },
})
console.log(data?.name) // 'Alice'The client proxy mirrors your route structure. Nested paths map to chained properties, dynamic params become function calls.
Next Steps
- Routing — full guide to HTTP routes, params, and groups
- Context — everything available inside a handler
- Validation — the
hschema reference - Error Handling — typed errors and custom responses
