Volt v0.1 · TypeScript APIs on Bun · Get started
Docs/Core Concepts/Context & Response API

Context & Response API

Read request data and return correctly formed HTTP responses.

Request data

APIValue
c.reqNative Request
c.paramsPath parameters; strings unless schema coercion applies
c.queryQuery values; repeated keys become arrays
c.headersNative Headers; read with get(name)
c.bodyParsed POST/PUT/PATCH body
c.storeApplication decoration store; shared across requests
c.url, c.path, c.methodParsed URL, pathname, and HTTP method

Complete example

index.ts
import { Volt } from 'voltts';

const app = new Volt();
app.get('/users/:id', (c) => {
  c.setHeader('X-Example', 'volt');
  return c.json({
    id: c.params.id,
    profile: c.query.profile === 'true',
    accept: c.headers.get('accept'),
  });
});
app.get('/text', (c) => c.text('Hello Volt'));
app.get('/html', (c) => c.html('<h1>Hello Volt</h1>'));
app.get('/redirect', (c) => c.redirect('/text'));
app.post('/echo', (c) => c.json({ body: c.body }, 201));
if (globalThis._importMeta_.main) app.listen(3000);
export default app;

Try request and response helpers

bash
bun run index.ts
curl -i 'http://localhost:3000/users/42?profile=true'
curl -i -X POST http://localhost:3000/echo -H 'Content-Type: application/json' -d '{"title":"Coffee"}'

Use c.json(data, status), c.text(text, status), c.html(html, status), c.redirect(url, status), and c.setHeader(name, value). Prefer explicit status arguments such as c.json(data, 201). A returned object becomes JSON; null or undefined becomes an empty 204 response.

Body and state rules

POST, PUT, and PATCH bodies are parsed before the handler. Use await c.parseBody() explicitly for methods outside that set when needed. Read multipart data with c.file(), c.files(), or c.formData(). Do not consume c.req.json() after automatic parsing. c.store is shared application state: keep per-request identity and temporary values in local variables rather than adding them to this store.