SSR framework for Svelte 5 + Bun with islands-based selective hydration
On this page
Utility helpers
Small functions exported from mochi-framework for shaping responses and form-action results. Each helper is documented in depth where it is used; this page is a single index.
Response helpers
json(data, init?): build a JSON Response with the right Content-Type. Use from Mochi.api() handlers and middleware.
import { json } from 'mochi-framework';
return json({ ok: true }, { status: 201 });error(status, message): throw a MochiHttpError that the framework catches and renders as the configured error page (or a JSON envelope from API routes). See Error handling.
import { error } from 'mochi-framework';
if (!user) error(404, 'User not found');apiError(status, message): return — don’t throw — a JSON error Response shaped as { error: { message, status } }. Use inside Mochi.api() when you want a typed error without unwinding the stack. See API routes.
import { apiError } from 'mochi-framework';
return apiError(400, 'Missing id');Form-action helpers
Used as return values from a Mochi.page action. See Defining routes and Progressive enhancement for the full action lifecycle.
fail(status, data): re-render the page with form = { ok: false, ...data } and the given HTTP status. Use for validation errors.
import { fail } from 'mochi-framework';
if (!username) return fail(400, { error: 'Username required', username });success(data?): re-render the page with form = { ok: true, ...data } and HTTP 200. Use when the action completes but you want to stay on the page.
import { success } from 'mochi-framework';
return success({ message: 'Saved.' });redirect(status, location): issue an HTTP redirect after the action runs. status must be 301, 302, 303, 307, or 308. Use 303 for the standard POST/Redirect/GET pattern.
import { redirect } from 'mochi-framework';
return redirect(303, '/dashboard');Sealed tokens
encryptPayload(plaintext, { aad?, compress? }) / decryptPayload(token, { aad? }): seal a string into an opaque, tamper-proof base64url token (AES-256-SIV keyed from MOCHI_KEY) and open it again. decryptPayload returns null on any tamper or aad mismatch. This is the same primitive Mochi uses for server-island props — use it for short-lived signed values like form challenges or magic links.
import { encryptPayload, decryptPayload } from 'mochi-framework';
const token = encryptPayload(JSON.stringify({ iat: Date.now() }), { aad: 'my-form' });
const opened = decryptPayload(token, { aad: 'my-form' }); // string | nullSee it in action
Live demos showing key concepts from this page