toiljs
v0.0.56
Published
The modern React framework: a file-based React frontend and a ToilScript-compiled WebAssembly backend.
Maintainers
Readme
ToilJS
Build better. Ship faster.
The first fullstack React framework for a globally distributed application delivery network.
React on the client. Your server compiled to WebAssembly, built to run on an edge runtime measured at 8 million requests/s on a single modern box.
Nothing to configure: routing, data, SEO, top-tier tooling, and full AI support, all built in.
⚡ Dynamic as fast as static. On the Toil edge runtime, running your server code is measured as fast as serving a static file.
⚡ First-class WebTransport over HTTP/3, with automatic WebSocket fallback.
- Built for scale
- Everything, at a glance
- Routing
- Data and caching
- Rendering and SEO
- Assets and the Vite build
- Components
- Realtime
- The server: ToilScript + WebAssembly
- Agentic tooling
- Configuration
- CLI
- Architecture
- The road to hyperscale
ToilJS is the first fullstack React framework built for a globally distributed application delivery network. That is the whole point. Most React frameworks are built for convenience and start to buckle the moment real traffic arrives. Toil is built the other way around: for scale that serves the millionth request as easily as the first. Your client ships as a static bundle to the edge, and your server compiles to a single portable module designed to run at line rate, so the app you write on your laptop is shaped from day one to take serious load instead of folding under it. On the Toil edge runtime that is not a slogan but a measurement: a request that runs your code is served as fast as a static file, so dynamic costs you nothing. The edge is not limited to CPU either: GPU hardware acceleration is coming, projected to take a single box from 8 million requests/s today to 50-200 million.
It is also the entire stack, already wired and configured: routing, data, caching, SEO, site search, an image and font pipeline, realtime, a dev toolbar with AI, and a strict toolchain. One command scaffolds it, then you build your app, not your stack. Nothing to assemble, nothing to glue, nothing to configure.
npx toiljs create my-app
cd my-app
npm run devDrop a .tsx file in client/routes/ and it is a route: typed, code-split, prefetched, with its data loaded before render. Your server/ is written in ToilScript (TypeScript syntax) and compiles to a single WebAssembly module. You configured nothing.
your app
┌──────────────────────┬──────────────────────┐
│ client/ │ server/ │
│ React + TSX │ ToilScript (.ts) │
│ static SPA bundle │ ──▶ WebAssembly │
└──────────┬───────────┴──────────┬───────────┘
│ │
▼ ▼
CDN / static host WASM edge runtime
└───── typed RPC ──────┘The client is fully static (host it anywhere). The server is a portable compiled module. The two are separated by design and joined by a typed contract, so the frontend ships to any CDN while the backend runs wherever it is deployed. That split is what makes the delivery network global: static files replicate everywhere for free, and one small module is trivial to run in many places at once.
Built for scale
Toil's architecture is the scaling story. There is no monolith to keep warm and nothing re-rendering your pages on every request.
- The client is static.
buildemits a plain SPA bundle with each route's HTML already prerendered. It has no runtime server dependency, so it ships to any CDN or edge network and is cached and served close to every user. - The server is one portable module. Your ToilScript backend compiles to a single self-contained module: no Node runtime to boot, no framework cold start, no per-request bootstrap. It is small, it starts instantly, and it runs the same everywhere.
- Client and server are decoupled. They are separate artifacts joined only by a typed contract, so the frontend scales as static files while the backend scales as stateless compute. Neither one bottlenecks the other.
- Shaped for the edge. That compiled module is exactly the unit a hyperscale edge runtime is built to serve: isolated per tenant, replicated across regions, run at line rate.
That platform is not hypothetical. The Toil edge runtime is built and measured; this is the stack that runs your app at planetary scale:
- A purpose-built edge runtime (built, measured): engineered from scratch to serve compiled apps at line rate, not adapted from a general-purpose web server. Your compiled server runs as a long-lived, isolated, per-tenant WebAssembly instance, with static assets served at wire speed alongside it. Measured at 8 million requests/s with sub-ms p50 on a single modern box, and the dynamic WebAssembly path runs at the same network-bound ceiling as serving a static file.
- First-class WebTransport (endpoint live, client API landing): the runtime already terminates QUIC + TLS 1.3 and speaks HTTP/3 and WebTransport (multiplexed bidirectional streams and datagrams, no head-of-line blocking), wired into the same per-tenant instances as HTTP. The framework's channel API falls back to WebSocket automatically, so the same
useChannelsimply runs on the fastest transport available. WebSocket channels work today. - Hyperscale security built in (built): every tenant is validated at deploy time and runs under a hard per-request CPU cap and a per-tenant memory budget, isolation is enforced below your code so nothing survives between requests or tenants, and a built-in firewall screens traffic before it ever reaches an app. Overload sheds gracefully instead of melting.
- ToilDB, edge-replicated typed data (next): typed collections where the method name tells you the cost, local-fast reads, CRDT writes that merge everywhere, owner-routed writes, and rare global claims that are explicitly slow. The async foundation it needs is already live in the runtime; the data layer itself is the next step.
- GPU hardware acceleration (coming): the Toil server will be able to tap GPU acceleration on the edge, so compute-heavy work (media, crypto, AI inference) runs on the hardware built for it instead of burning CPU, with a single box projected to reach 50-200 million requests/s (moderate estimate).
- Post-quantum-ready transport (coming): forward-looking encryption on the QUIC layer that is already terminating TLS 1.3.
- Dacely Cloud (coming): managed hosting for the whole stack, push the app and the client goes to the edge while the server runs on the runtime.
The same app runs on your laptop and is shaped, from the first commit, to fan out across the edge without a rewrite. Full architecture and status in The road to hyperscale.
Everything, at a glance
This is the full surface area. Every row works the moment create finishes, no plugins to install, no config to write.
| | |
| --- | --- |
| Zero config | One command scaffolds a working app. You never write an index.html, a main.tsx, a router, or a Vite / build config. The framework generates and owns all of it. |
| Routing | File-based. Dynamic, catch-all, optional catch-all, route groups, nested layouts, templates, loading and error boundaries, parallel slots, and intercepting routes. Every href and params is typed against your real files. |
| Navigation | Link / NavLink, programmatic navigate / back / forward / refresh, hover and viewport prefetch, scroll restoration, instant back/forward, and animated view transitions. |
| Data | A loader resolves before render. useAction / <Form> write then revalidate. An LRU loader cache with per-route revalidate. No fetch waterfalls, no useEffect data fetching. |
| Rendering + SEO | Per-route <head> baked into static HTML at build, plus sitemap.xml, robots.txt, llms.txt, OpenGraph, Twitter, JSON-LD, canonical, theme-color, early hints. SSG via generateStaticParams. |
| Search | Built-in site search over a compiler-baked metadata index, ranked, with a usePageSearch hook. Plus llms.txt so AI crawlers can read your site. |
| Assets | Imported images compressed to webp and resized via Vite + sharp. Fonts preloaded. React split into its own long-lived chunk. The build logs what it saved. |
| Components | Drop-in Image (no layout shift, lazy, blur), Script (load strategies, dedupe), Form, Slot, Head, all on a typed Toil global, zero imports. |
| Realtime | Typed channels: connectChannel / useChannel, reconnect built in, text or binary frames. WebSocket today, with first-class WebTransport over HTTP/3 coming (automatic WebSocket fallback). |
| Server | A typed ToilScript server compiled to a portable, native-speed module. Request / Response REST handlers, binary IO on both sides, and a typed RPC surface generated from your server. |
| Agentic DX | A dev toolbar with a live AI tab (hand off page context to Claude or ChatGPT), a Cmd+K palette, and scaffolded agent files (CLAUDE.md, AGENTS.md, Cursor, Copilot). |
| Toolkit | Strict TypeScript, ESLint, and Prettier shipped as presets, plus optional git init. Tailwind v4, Sass, Less, and Stylus a flag away. |
| CLI | create, dev, build, start, configure, doctor (with --json for CI), and update. |
Routing
The filesystem is the router. Every convention below is implemented.
| File or folder | Route |
| --- | --- |
| index.tsx | / |
| about.tsx | /about |
| blog/[id].tsx | /blog/:id |
| docs/[...slug].tsx | catch-all |
| docs/[[...slug]].tsx | optional catch-all |
| (marketing)/about.tsx | route group, adds no URL segment |
| layout.tsx | wraps the segment, persists across navigation |
| template.tsx | a layout that re-mounts on every navigation |
| loading.tsx | Suspense fallback while the route and its data load |
| error.tsx | error boundary for the segment |
| global-error.tsx | catches errors in the root layout itself |
| 404.tsx | not-found page |
| @modal/... | parallel slot, placed with <Toil.Slot name="modal" /> |
| @modal/(.)photo/[id] | intercepting route: modal on soft nav, full page on reload |
Navigation comes with it:
<Toil.Link>and<Toil.NavLink>(active class +aria-current), withhrefchecked against your real routes.navigate/back/forward/refresh, plususeRouter,useNavigate,useLocation,usePathname,useParams,useSearchParams,useNavigationPending.- Hover and viewport prefetching, so chunks (and data) are warm before you click. Respects
saveDataanddata-no-prefetch. - Scroll restoration on back/forward, scroll-to-
#hash, and scroll-to-top on new routes. - Instant navigation: visited pages render synchronously, no flash.
- View transitions (
client.viewTransitions: true) for animated page changes, respectingprefers-reduced-motion.
Data and caching
Read with a loader, write with an action. Both keep the UI in sync without manual refetching, and the client caches loader results so repeat navigations are instant.
export const loader = async ({ params }: Toil.LoaderArgs) => fetchPost(params.id);
export const revalidate: Toil.Revalidate = 10; // reuse for 10s, false = forever, omit = every nav
function SaveButton({ title }: { title: string }) {
const save = Toil.useAction((t: string) => api.save(t), { revalidate: true });
return (
<button disabled={save.pending} onClick={() => void save.run(title)}>
{save.pending ? 'Saving' : 'Save'}
</button>
);
}loaderresolves in parallel with the route chunk; the page suspends until ready (itsloading.tsxshows).useLoaderData(loader)is typed straight from the loader, no generics.- Client cache: an LRU of loader results keyed by path + search, with
revalidateset per route (seconds,falsefor forever, or per-navigation). Prefetched entries are reused on commit. useActionand<Toil.Form>track pending and error state and revalidate the routes you name on success.router.revalidate()/revalidate(href)bust the cache after a mutation.
Rendering and SEO
A single-page app serves an empty shell. ToilJS pre-renders each route's <head> at build, so Google, Facebook, Discord, Slack, and the AI crawlers see real per-page tags without running your JavaScript.
// toil.config.ts
export default defineConfig({
client: {
seo: {
url: 'https://example.com',
title: 'My App',
openGraph: { siteName: 'My App', type: 'website', image: '/og.png' },
twitter: { card: 'summary_large_image' },
jsonLd: { '@context': 'https://schema.org', '@type': 'WebSite' },
themeColor: '#2563ff', // also the Discord / Slack embed accent
preconnect: ['https://cdn.example.com'],
robots: { ai: 'allow' },
},
},
});- Per-route
metadata(orgenerateMetadataderived from the loader's data) wins per page over layout defaults. - Static prerender writes a
<route>/index.htmlfor every static route with that route's head baked in. SSG enumerates dynamic routes viagenerateStaticParamsand bakes per-URL HTML. robots.txt,sitemap.xml, andllms.txtgenerated together.- Full OpenGraph, Twitter card, JSON-LD, canonical, theme-color, and
preconnect/dns-prefetchearly hints. Output is XSS-hardened.
AI search, on by default
Turn on SEO and the build emits an llms.txt describing your site for language models, plus a robots.txt with explicit per-bot rules. Allow or block GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, anthropic-ai, Google-Extended, PerplexityBot, CCBot, Applebot-Extended, Bytespider, Amazonbot, and Meta-ExternalAgent with one switch:
seo: { llms: { instructions: 'Docs live at /docs.' }, robots: { ai: 'disallow' } }Your users get search too. The compiler bakes a static index of every page's title, description, and keywords, and Toil.usePageSearch (or the pure searchPages) returns ranked, navigable results.
Assets and the Vite build
ToilJS owns Vite, for the dev server and for the ahead-of-time production build, and does the boring optimization for you. The build tells you what it did:
$ npm run build
✓ optimized 3 images
client/hero.png
→ images/hero.webp 148.0 kB → 19.3 kB -87%
✓ preloaded 2 fonts
→ fonts/inter-latin.woff2 24.10 kB- Images (Vite imagetools + sharp): every imported raster is compressed to webp, with resize and reformat via
?w=400;800&format=webp&as=srcset. The build logs the savings. - Fonts: bundled
@font-facefonts get a<link rel="preload">so text paints sooner, also logged. - Chunking: React is split into its own long-lived chunk; assets land in tidy
images/,fonts/, andcss/folders. - Node polyfills (
Buffer,global,process) for libraries that expect them. - Styling: plain CSS out of the box, with Sass, Less, Stylus, and Tailwind v4 a
toiljs configureaway.
You never write an index.html, a main.tsx, or a Vite config. The framework generates and owns them.
Components
Zero-import, on the Toil global:
Imagedrops in for<img>: reserves space (no layout shift), lazy-loads, async-decodes,priorityfor the LCP image,fill+objectFit, optional blur placeholder.Scriptloads external or inline scripts with astrategy(afterInteractive/lazyOnload/beforeInteractive), deduplicated so a script never runs twice.Formsubmits to an action without a reload, revalidates on success, exposes pending state, optionally resets fields.Slotrenders a parallel@slotroute, the basis for modal overlays.Head/useHead/useTitleset the title and<meta>/<link>tags imperatively and compose across the tree.
Realtime
One typed channel API for live data in both directions.
const messages = Toil.useChannel<Message>('/chat');connectChannel / useChannel / resolveChannelUrl handle connection, reconnection, and message decoding, text or binary frames. Today the channel runs over WebSocket. Next it rides WebTransport over HTTP/3: multiplexed bidirectional streams and datagrams over QUIC with no head-of-line blocking. The server side already exists: the Toil edge runtime terminates QUIC + TLS 1.3 and hands WebTransport sessions to the same per-tenant WebAssembly instance that serves your HTTP requests. Toil is built to be the first framework to ship first-class WebTransport, with automatic WebSocket fallback, so the same useChannel quietly upgrades to the fastest transport the client and network support, with no code change.
The server: ToilScript + WebAssembly
Your backend is written in ToilScript, a TypeScript-syntax language that compiles to WebAssembly. You write request handlers; the compiler produces a single portable .wasm module.
// server/HelloHandler.ts
export class HelloHandler extends ToilHandler {
handle(req: Request): Response {
if (req.path == '/api/hello') return Response.json('{"hello":"world"}');
return Response.notFound();
}
}- REST handlers:
Request(method, path, headers, body) in,Responseout, withtext/html/json/notFound/badRequest/internalErrorhelpers and the full set of HTTP methods. - Binary IO on both sides:
DataWriter,DataReader,FastMap, andFastSetare shared client and server globals (andtoiljs/io), so you can move structured bytes instead of paying the JSON tax. - Typed RPC (preview): tag a server function and the compiler generates a typed
Server.*surface on the client, end to end, no hand-written glue. The typed pipeline is in place today; the network transport is landing next. - Cookies: a complete RFC 6265bis layer as a global (no import). Read with
req.cookie('sid'), write withresp.setCookie(Cookie.create('sid', token).httpOnly().secure().sameSite(SameSite.Lax)), and reach forSecureCookieswhen you need HMAC-signed or AES-256-GCM-encrypted values.
toiljs start self-hosts the built client and a WebSocket channel on hyper-express (backed by uWebSockets.js) for local and small deployments. At scale, that same .wasm is exactly what the Toil edge runtime serves: one hot instance per tenant, called directly with your request and wiped clean between requests, so there is no cold start and isolation is enforced below your code rather than by trust. See The road to hyperscale.
Agentic tooling
toiljs dev injects a floating toolbar (stripped from production builds entirely, no flag, no leftover bytes) that surfaces the framework's live state: the matched route, params, and active slots; the loader cache with revalidate and clear buttons; the live <head> with an OpenGraph preview and an SEO checklist; resolved config flags and versions; a captured error log; and toggles for view and loader transitions. Press Cmd/Ctrl+K for a command palette to jump to any route or run a dev action.
It also ships an AI tab: hand off the current page's context (and its source) to Claude or ChatGPT in one click, or wire a provider for inline answers. The API key is read server-side only and never reaches the browser.
import { defineConfig, AiProvider } from 'toiljs/compiler';
export default defineConfig({
client: {
devtools: {
ai: {
provider: AiProvider.Anthropic, // or AiProvider.OpenAI, or a custom endpoint
model: 'claude-sonnet-4-6',
apiKeyEnv: 'ANTHROPIC_API_KEY', // read by the dev server only
},
},
},
});The toiljs create wizard also scaffolds assistant files (CLAUDE.md, AGENTS.md, Cursor, and Copilot configs) so your repo is ready for coding agents on day one.
The toolkit is the standard
ToilJS sets the toolchain so nobody argues about it. Strict TypeScript, ESLint (typescript-eslint, react-hooks, react-refresh, @eslint-react), and Prettier come configured and enforced from the first commit, shipped as toiljs/tsconfig, toiljs/eslint, and toiljs/prettier. New apps extend them automatically and can init git in the same step. Opt in to as much as you want, nothing to copy, nothing to bikeshed.
Configuration
One file, toil.config.ts, typed with defineConfig. Every option has a sensible default, so most apps only set seo.
import { defineConfig } from 'toiljs/compiler';
export default defineConfig({
client: {
srcDir: 'client', // source root (default: client)
routesDir: 'routes', // route folder (default: routes)
base: '/', // base path (default: /)
port: 3000, // dev / start port (default: 3000)
images: true, // webp + resize pipeline (default: true)
fonts: true, // preload bundled fonts (default: true)
viewTransitions: false, // animated navigation (default: false)
transitions: false, // keep page during load (default: false)
devtools: true, // dev toolbar, or { ai } (default: true)
seo: {
// url, title, openGraph, twitter, jsonLd, robots, themeColor, ...
},
vite: {
// escape hatch: a full Vite InlineConfig, merged on top
},
},
});Set any feature to false to turn it off. client.vite is merged into the generated Vite config for the rare case you need to reach the bundler directly.
CLI
toiljs create [name] scaffold a new app
toiljs dev dev server with HMR
toiljs build ahead-of-time production build
toiljs start self-host the built client + realtime channel
toiljs configure toggle styling and asset features on an existing app
toiljs doctor diagnose project setup and dependencies
toiljs update check for and apply dependency updatescreate [name]runs an interactive wizard: template (apporminimal), CSS flavor (css/sass/less/stylus), Tailwind, which AI assistant files to scaffold, image optimization, git init, and package manager (npm/pnpm/yarn/bun). Every prompt has a flag (--template,--style,--tailwind,--ai,--images,--git,--install,--pm), and--yesruns it non-interactively.devstarts the Vite dev server with HMR and regenerates the route table as you add or remove files.--portto override.buildproduces the optimized static client: prerendered HTML,sitemap.xml,robots.txt,llms.txt, and compressed images and fonts.startself-hosts the build and a realtime channel at/_toilon hyper-express.--port(default 3000),--host(pass0.0.0.0to expose on the network).configureedits an existing app: switch CSS preprocessor, toggle Tailwind or image optimization, and sync dependencies.doctorruns read-only checks across environment, routing, config, assets, and the server build, with a fix hint on each.--jsonfor CI; it exits non-zero when a check fails.updatechecks the registry and groups available updates by major / minor / patch; pick what to apply or pass-yfor all (--targetsets the strategy).
Every command also verifies you are on the latest toiljs, both the project install and the global CLI, and prints a boxed warning with the exact update command when one is behind. The registry answer is cached for an hour and the check never slows down or fails your build; opt out with TOILJS_NO_UPDATE_CHECK=1.
One file does a lot
// client/routes/posts/[id].tsx -> /posts/:id
interface Post {
title: string;
}
export const metadata: Toil.Metadata = { title: 'Post' }; // SEO, baked into the HTML at build
export const loader = async ({ params }: Toil.LoaderArgs): Promise<Post> => {
const res = await fetch(`/api/posts/${params.id}`); // runs before render, no useEffect
return res.json();
};
export default function PostPage() {
const post = Toil.useLoaderData(loader); // typed Post, no generics
return (
<article>
<h1>{post.title}</h1>
<Toil.Link href="/posts">All posts</Toil.Link> {/* href is type-checked */}
</article>
);
}No imports. Toil is a fully-typed global, tree-shaken at build. The page renders with its data already loaded.
Architecture
One pipeline, from your editor to planetary scale. The build pipeline and the React client ship today; the edge runtime is built and measured (purple = not yet GA), and the ToilDB data layer and Dacely Cloud are the roadmap.
flowchart TB
classDef today fill:#0e1520,stroke:#2563ff,stroke-width:2px,color:#cfe0ff;
classDef soon fill:#160f1f,stroke:#7c3aed,stroke-width:2px,color:#ead7ff,stroke-dasharray:6 4;
subgraph BUILD["BUILD, toiljs CLI, shipping today"]
direction TB
TSX["client/ React + TSX routes"] --> VITE["Vite<br/>HMR + ahead-of-time build"] --> ART["static client<br/>prerendered HTML<br/>sitemap, robots, llms<br/>optimized images + fonts"]
TS["server/ ToilScript .ts"] --> TSC["toilscript compiler"] --> WASM["one .wasm module"]
TOOL["toolkit: TypeScript, ESLint, Prettier, git<br/>dev toolbar: routes, loader cache, head/OG, errors<br/>AI tab to Claude / ChatGPT, Cmd-K palette<br/>typed RPC surface Server.*"]
end
CLIENTS["CLIENTS<br/>browsers, mobile, API clients, AI crawlers / LLMs"]
subgraph EDGE["EDGE, anycast, multi-region POPs, scale-out, built + measured, pre-GA"]
direction LR
SC["STATIC CLIENT<br/>React SPA + baked HTML<br/>images, fonts, css<br/>served from CDN / edge"]
RT["WASM EDGE RUNTIME<br/>your ToilScript server as one .wasm<br/>isolated per-core tenant at line rate<br/>8M req/s measured, sub-ms p50<br/>Request to handler to Response<br/>realtime channels, binary IO<br/>x many tenants x many POPs"]
SC <-->|"typed RPC Server.*"| RT
end
subgraph DATA["ToilDB, edge-replicated typed data, roadmap"]
direction LR
MODES["collections<br/>owned, eventLog, counter, set<br/>unique, escrow, snapshot<br/>local reads fast, CRDT writes merge everywhere<br/>owned writes fast at owner, global claims slow"]
DUR["durable store<br/>structured records"]
BLOB["blob store<br/>large objects"]
MODES --> DUR
MODES --> BLOB
end
CTRL["DACELY CLOUD, control plane, roadmap<br/>deploy, distribute, scale<br/>client to the edge, .wasm to the runtime, data replicated"]
ART -->|deploys| SC
WASM -->|deploys| RT
CLIENTS -->|"HTTP/1.1 + WebSocket today<br/>HTTP/3, QUIC, WebTransport roadmap<br/>TLS today, post-quantum roadmap"| EDGE
RT -->|"region-replicated"| DATA
CTRL -. orchestrates .-> EDGE
CTRL -. orchestrates .-> DATA
class TSX,VITE,ART,TS,TSC,WASM,TOOL,CLIENTS today;
class SC,RT,MODES,DUR,BLOB,CTRL soon;┌──────────────────────────────────────────────────────────────────────────┐
│ BUILD toiljs CLI [today] │
│ │
│ client/ React + TSX routes ──▶ Vite (HMR ahead-of-time build) ──┐ │
│ server/ ToilScript (.ts) ──▶ toilscript compiler ──▶ one .wasm │ │
│ │ │
│ toolkit TypeScript ESLint Prettier git (opt-in presets) │ │
│ dev toolbar: routes loader cache head/OG errors │ │
│ AI tab → Claude / ChatGPT ⌘K palette │ │
│ emits static client prerendered HTML sitemap robots llms │ │
│ optimized images / fonts typed RPC surface (Server.*) │ │
└───────────────────────────────────────────────────────────────┬─────┬───┘
deploys ▼ │ │ ▼
┌──────────────────────────────────────────────────────────────────────────┐
│ CLIENTS │
│ browsers mobile webviews API clients AI crawlers/LLMs │
└───────────────────────────────────┬──────────────────────────────────────┘
HTTP/1.1 + WebSocket [today] │ HTTP/3 QUIC WebTransport [soon]
TLS [today] │ post-quantum transport [soon]
▼
╔══════════════════════════════════════════════════════════════════════════╗
║ EDGE anycast multi-region POPs scale-out [built] ║
║ ║
║ ┌─────────────────────────┐ ┌─────────────────────────────────┐ ║
║ │ STATIC CLIENT │ │ WASM EDGE RUNTIME │ ║
║ │ React SPA + baked HTML │ │ your ToilScript server as one │ ║
║ │ images fonts css │ typed│ .wasm, run as an isolated │ ║
║ │ served from CDN / edge │◀──RPC─▶│ per-core tenant at line rate │ ║
║ │ │ Server.* Request ▶ handler ▶ Response │ ║
║ │ llms robots sitemap │ │ realtime channels binary IO │ ║
║ └─────────────────────────┘ └───────────────┬─────────────────┘ ║
║ instant, cacheable × many tenants × many POPs ║
╚═══════════════════════════════════════════════════════╪══════════════════╝
▼ region-replicated
╔══════════════════════════════════════════════════════════════════════════╗
║ ToilDB edge-replicated, typed data layer [soon] ║
║ ║
║ collections: owned eventLog counter set unique escrow ║
║ snapshot (the method name tells you the cost) ║
║ local reads fast CRDT writes merge everywhere ║
║ owned writes fast at the owner global claims explicitly slow ║
║ ║
║ ┌──────────────────────┐ ┌──────────────────────┐ ║
║ │ durable store │ │ blob store │ ║
║ │ structured records │ │ large objects │ ║
║ └──────────────────────┘ └──────────────────────┘ ║
╚═══════════════════════════════════════════════════════╪══════════════════╝
▼
╔══════════════════════════════════════════════════════════════════════════╗
║ DACELY CLOUD control plane: deploy distribute scale [soon] ║
║ push your app ─▶ client to the edge, .wasm to the runtime, data replicated ║
╚══════════════════════════════════════════════════════════════════════════╝
[today] shipping now [built] running + measured, not yet GA [soon] roadmapThe road to hyperscale
Architecture and status. The framework above is what ships in the box today. The edge runtime below is built and measured, not yet generally available. ToilDB and Dacely Cloud are the roadmap.
The reason the client is static and the server is WebAssembly is that the WebAssembly runs on a runtime engineered from scratch for the edge. Toil's backend treats your compiled server as an isolated tenant and serves it at line rate, so the same app that runs on your laptop scales out across the edge without a rewrite.
- A purpose-built WebAssembly edge runtime (built, measured). Your server runs as an isolated WebAssembly tenant on a runtime engineered for line-rate, multi-gigabit throughput and per-tenant isolation, not on a general-purpose Node process. On a single modern box it sustains 8 million requests/s at sub-millisecond p50 across thousands of concurrent connections, the dynamic WebAssembly path runs as fast as serving a static file, deploys hot-swap with no restart, and there are no cold starts.
- HTTP/3 and WebTransport (endpoint live). The runtime terminates QUIC + TLS 1.3 and speaks HTTP/3 and WebTransport: bidirectional streams and datagrams for interactive, multiplexed realtime, beyond the WebSocket channel that ships today.
- Hardened multi-tenancy (built). Tenants are validated at deploy time, every request runs under a hard CPU cap and memory budget, nothing survives between requests or tenants, traffic is screened before it reaches an app, and overload sheds gracefully. The isolation model is security-audited and soak-tested.
- ToilDB, an edge-replicated data layer (next). Typed collections declared in ToilScript, where the method name tells you the cost: local reads are fast, appends and CRDT counters/sets merge everywhere, owned writes are fast at the owner, and rare global claims are explicitly slow. Hyperscale data, without a per-query consistency knob to get wrong. The async foundation it needs is already live in the runtime.
- GPU hardware acceleration (coming). Compute-heavy workloads in your server (media, crypto, AI inference) will offload to GPU hardware on the edge, scaling past what CPU cores alone can do, a single box is projected to reach 50-200 million requests/s (moderate estimate).
- Post-quantum-ready transport (coming). Forward-looking encryption on the QUIC layer that already terminates TLS 1.3.
- Dacely Cloud (coming). Managed hosting for the whole stack: push your app, the static client goes to the edge and your WebAssembly server runs on the runtime above.
This is the spine the framework was shaped around. Today you write a typed, file-based React app with a WebAssembly server; the platform that runs it at planetary scale is already standing in the lab.
Tech
React 19, TypeScript, Vite, ToilScript (TypeScript syntax, compiles to WebAssembly), Vite imagetools + sharp, ESLint (typescript-eslint, react-hooks, react-refresh, @eslint-react), Prettier, Tailwind v4 (optional).
Start
npx toiljs create my-appEverything in the framework half of this README is already on. You just build the app.
