Framework handler API reference
Exact factories, options, signatures, mounting examples, origin requirements, and runtime behavior for every Ownfold framework package.
Framework packages adapt the canonical Fetch handler to route conventions. They do not configure a database, authenticate users, create browser clients, or render UI.
Shared setup
Every handler ultimately receives VaultFetchHandlerOptions:
serverVaultServer
VaultServerbasePath?string
stringisOriginAllowed?(input: { readonly request: Request }) => boolean | Promise<boolean>
(input: { readonly request: Request }) => boolean | Promise<boolean>Create vaultServer once, then mount exactly one framework adapter. Keep the mount path equal to
the browser transport’s baseURL.
Next.js App Router
pnpm add @ownfold/next@beta
import { createNextVaultHandlers } from "@ownfold/next"
import { vaultServer } from "@/src/lib/vault-server"
export const { GET, POST } = createNextVaultHandlers({
server: vaultServer,
basePath: "/api/ownfold",
})
createNextVaultHandlers(options)
Returns NextVaultHandlers, an object with (request: Request) => Promise<Response> functions for
GET and POST. Export both from the catch-all route. Unsupported methods remain absent and are
handled by Next.js.
GET(request: Request) => Promise<Response>
(request: Request) => Promise<Response>POST(request: Request) => Promise<Response>
(request: Request) => Promise<Response>This package is server-only. Do not import it into Client Components or the Edge runtime unless all selected server/database dependencies support that runtime.
Standard Node.js
pnpm add @ownfold/node@beta @ownfold/fetch@beta
import { createVaultFetchHandler } from "@ownfold/fetch"
import { createNodeVaultHandler } from "@ownfold/node"
const handler = createNodeVaultHandler({
handler: createVaultFetchHandler({ server: vaultServer }),
origin: process.env.PUBLIC_APP_ORIGIN,
})
httpServer.on("request", (request, response) => {
void handler(request, response)
})
handlerVaultFetchHandler
VaultFetchHandleroriginNodeVaultOrigin
NodeVaultOriginmaxBodyBytes?number
number| Option | Required behavior |
|---|---|
handler |
Canonical VaultFetchHandler to invoke after conversion. |
origin |
Exact public origin or resolver used to construct the standard Request URL. Never derive trust from an unvalidated Host header. |
maxBodyBytes |
Native request-stream ceiling; defaults to the canonical HTTP maximum. |
createNodeVaultHandler converts Node request headers, URL, method, and bounded body to a standard
Request, invokes the Fetch handler, then writes status, headers, and body back once.
createExpressVaultMiddleware has the same option and return types. Mount it at the application
level so the Fetch handler can see its configured base path:
app.use(
createExpressVaultMiddleware({
handler: createVaultFetchHandler({ server: vaultServer }),
origin: "https://app.example.com",
}),
)
Fastify
pnpm add @ownfold/fastify@beta
import { createFastifyVaultHandler } from "@ownfold/fastify"
const handler = createFastifyVaultHandler({
server: vaultServer,
basePath: "/api/ownfold",
origin: "https://app.example.com",
})
fastify.route({
method: ["GET", "POST"],
url: "/api/ownfold/*",
handler,
})
originNodeVaultOrigin
NodeVaultOriginmaxBodyBytes?number
numberThe handler uses request.raw and reply.raw, then calls reply.hijack() so Fastify does not write
a second response. origin and maxBodyBytes have the Node adapter semantics.
Hono
pnpm add @ownfold/hono@beta
import { createHonoVaultHandler } from "@ownfold/hono"
app.all(
"/api/ownfold/*",
createHonoVaultHandler({ server: vaultServer }),
)
createHonoVaultHandler(options) returns a native Hono Handler. It forwards context.req.raw to
the Fetch handler and returns its Response. Use Hono middleware before the route for host session,
CSRF, tracing, or request correlation.
Elysia
pnpm add @ownfold/elysia@beta
import { createElysiaVaultHandler } from "@ownfold/elysia"
const ownfold = createElysiaVaultHandler({ server: vaultServer })
app.all("/api/ownfold/*", ({ request }) => ownfold({ request }))
createElysiaVaultHandler(options) returns
(context: { request: Request }) => Promise<Response>. Pass Elysia’s standard Request unchanged.
TanStack Start
pnpm add @ownfold/tanstack-start@beta
import { createTanStackStartVaultHandlers } from "@ownfold/tanstack-start"
import { createFileRoute } from "@tanstack/react-router"
const handlers = createTanStackStartVaultHandlers({
server: vaultServer,
})
export const Route = createFileRoute("/api/ownfold/$")({
server: {
handlers,
},
})
GET(input: TanStackStartServerRouteInput) => Promise<Response>
(input: TanStackStartServerRouteInput) => Promise<Response>POST(input: TanStackStartServerRouteInput) => Promise<Response>
(input: TanStackStartServerRouteInput) => Promise<Response>Each function accepts { request }, matching TanStack Start server-route callbacks, and returns the
canonical response.
Choosing the generic Fetch handler
Use createVaultFetchHandler directly when the framework already provides standard web Requests
and expects standard Responses. A dedicated package is useful only when its native handler shape
differs or a typed convenience avoids glue code.
Handler invariants
All official framework handlers preserve the same behavior:
- no browser-provided user ID;
- exact bounded-body parsing before JSON validation;
- the configured server’s authentication, rate-limit, and audit pipeline;
- stable HTTP error mapping without internal causes;
- no application-record persistence; and
- no default hosted Ownfold service or outbound telemetry.
See Transport APIs, Vault server, and the complete export index.