bext.dev
DocsApplication Toolkit
Application Toolkit3 min read
On this page

Application Toolkit

bext ships two layers of building blocks. The Capabilities (see the Capabilities section) are Rust plugin traits — server-side seams for config validation, payment providers, mailers, feature flags and so on. The Application Toolkit is the layer above them: ergonomic TypeScript primitives a PRISM site author imports directly and uses inside a loader, an action, or a component. No plugin to register, no IPC — most of it is pure, dependency-free TypeScript that runs in the same isolate as your render.

If you come from Laravel, this is the layer you know as the facades and helpers — Validator::make, Gate::allows, Eloquent, Notification::send, Cashier. Same job, TypeScript-native, sitting on top of bext's runtime and the Rust capabilities.

Modules#

Import What it gives you Rust capability it complements
@bext-stack/framework/validation Typed schema validation for FormData / JSON, multi-error reports, server-action helper. Request Validator
@bext-stack/framework/auth Cookie utils, tamper-proof HMAC-signed sessions, OAuth/OIDC PKCE — pure-JS crypto, no node:crypto. Auth / Session
@bext-stack/framework/authz Gates & policies — can / authorize, null-safe role & permission helpers, super-admin before hook. AuthzPolicy
@bext-stack/framework/orm + /migrate Typed model / query-builder + a tracked, idempotent migration runner and schema builder over embedded SQLite. Bridge
@bext-stack/framework/notifications One notify() fanning out to email / SMS / Slack / in-app / webhook, each channel rendered from the same Notification. Mailer
@bext-stack/framework/flags Code-defined feature flags & experiments — deterministic sticky percentage rollouts, with optional fall-through to the Rust engine. Feature Flag
@bext-stack/framework/billing Cashier-style Stripe checkout / portal / subscriptions + constant-time webhook signature verification, no Stripe SDK. Payment Providers
@bext-stack/framework/events Typed in-process domain event bus — decoupled listeners, async fan-out, subscribe map.
@bext-stack/framework/i18n Message catalogs with interpolation + pluralization, fallback locale, request locale detection. I18n
@bext-stack/framework/jobs Typed background jobs — dispatch() over the SDK queue, process() with automatic retries, pluggable transport. Background Jobs
@bext-stack/framework/kv Value cache — remember/get/put/pull/add over a pluggable store (SDK KV or in-memory). Caching
@bext-stack/framework/rate-limit Fixed-window rate limiting — check/attempt/peek/reset, allowed/remaining/retry-after, keyForRequest. Security
@bext-stack/framework/mail Transactional email templating — renderMailable(spec) → responsive HTML + plaintext, composes with notifications. Mailer
@bext-stack/framework/testkit + /testing Model factories + a route test client (testRoute), plus a component render/query library — all in bun test.

More modules land here as the toolkit grows (authorization, data & migrations, notifications, billing). Each one is a single subpath import, ships with a runnable demo on demo.bext.dev, and cross-links to the Rust capability it sits on top of.

Design rules#

Every toolkit module follows the same three rules, so they compose predictably:

  • Pure where it can be. Validation, schema building and formatting are plain TypeScript with no host calls — identical behaviour on V8 and QuickJS, and unit-testable with bun test and no bridge. State-touching modules go through the documented runtime seams (the sdk client, the native bridge globals) rather than inventing new ones.
  • Subpath imports only. Reach each module at its subpath (@bext-stack/framework/validation), never the barrel root — the barrel trips the turbopack pipeline.
  • Typed by construction. The types you write are the types you get back (Infer<typeof schema>), so the editor and tsc catch shape mistakes before a request ever runs.

See Also#

Edit this page ↗Need a hand? ↗
FIND YOUR NEXT STEP

Start with a topic, a command, or a question.