toiljs 0.0.102 → 0.0.104

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,51 +1,70 @@
1
1
  # What makes toil hyper-scalable
2
2
 
3
- **Hyper-scale** is serving very large, worldwide traffic at low latency without rebuilding your app as it grows. The test: when traffic goes from a thousand users to a hundred million across every continent, do you rewrite the system, or just run more of it?
3
+ Hyper-scale means serving very large worldwide traffic at low latency without rebuilding your app as it grows. The test is simple. Traffic climbs from a thousand users to a hundred million across every continent. Do you rewrite the system, or just run more of it?
4
4
 
5
- Most stacks scale the easy half (serving pages and cached reads from many places) but leave the hard half (writes, where data actually changes) in one region, so they slow down at once when enough far-away users start writing. toil scales both halves out together. It promises a design where scaling is cheap, adding more identical edge nodes with no central part everything funnels through, not a specific requests-per-second number.
5
+ Any stack can reach that scale if you spend enough: dedicated infrastructure per app, a rented vendor for each moving part, and an ops team to keep the seams from tearing. toil reaches the same scale from the other direction, cheaply. The whole design aims to make worldwide reach a default, not a budget line. This page is about cost.
6
6
 
7
- ## The mechanisms
7
+ ## Why serving the whole world is normally expensive
8
8
 
9
- **1. Compute next to the user.** toil has no origin server. Your `server.wasm` and its database are replicated to the [edge](../concepts/tiers.md) and run on the node nearest each user, so there is no slow hop to a faraway box. This is the biggest latency win, and the rest of the design exists to support it.
9
+ Running near your users usually means paying in three places at once.
10
+
11
+ - **Dedicated infrastructure per app.** Each app gets its own boxes, its own containers, its own always-warm capacity. Spread that across many cities and you rent a lot of mostly-idle hardware.
12
+ - **A far-away origin.** Most stacks serve pages from everywhere but send anything real back to one origin in one region. Every write and every dynamic call pays for a round trip across the planet.
13
+ - **A centralized write database.** Reads scale out. Writes funnel into one primary in one city. That box is both the bottleneck and the thing you overprovision to stay ahead of.
14
+
15
+ These are cost multipliers, and they stack. toil removes all three.
16
+
17
+ ## The three things that make toil cheap
18
+
19
+ Three mechanisms do the work, and they reinforce each other.
20
+
21
+ **1. Density: one box safely runs many apps.** Your backend compiles to its own tiny [sandboxed](./how-it-works.md#what-build-produces) WebAssembly module. It starts fast, runs at near-native speed, and cannot touch another tenant's files, memory, or network. Because the sandbox is that tight, one shared edge box holds many apps at once instead of one app per machine. That density is what makes running near everyone affordable. You are not renting dedicated hardware in fifty cities. You are one tenant on boxes that are already there and already busy.
22
+
23
+ **2. Edge locality: no trip to a central origin.** toil has no origin server. Every request runs on the [edge](../concepts/tiers.md) node nearest the user, on the per-request L1 hot path. The network hands the bytes to the WASM host, your handler runs, and the response goes back, all in one place. There is no slow hop to a faraway box to make the request real. Removing the origin removes both the latency and the standing cost of running one.
24
+
25
+ **3. Local reads, homed writes.** The data your handlers share lives in [ToilDB](../database/README.md), replicated outward so every edge node reads from a copy right next to it. Writes are not centralized. Every key has one home region that orders its writes, and the data replicates out for fast local reads. You get nearby reads everywhere without a single primary that every write funnels through, and without paying to overprovision one. The [distributed writes](./distributed.md) page covers the mechanism and its honest trade-off, eventual consistency.
10
26
 
11
27
  ```mermaid
12
28
  flowchart LR
13
- subgraph Origin["Everything funnels to one origin"]
29
+ subgraph Origin["The expensive shape: everything funnels to one origin"]
14
30
  direction TB
15
31
  A1["User (Tokyo)"] -->|slow| O[("Origin + DB<br/>(Virginia)")]
16
32
  A2["User (Paris)"] -->|slow| O
17
33
  A3["User (Sydney)"] -->|slow| O
18
34
  end
19
- subgraph Toil["Edge + distributed DB scales out"]
35
+ subgraph Toil["The cheap shape: shared edge + homed writes"]
20
36
  direction TB
21
- B1["User (Tokyo)"] --> E1["Edge + data (Tokyo)"]
22
- B2["User (Paris)"] --> E2["Edge + data (Paris)"]
23
- B3["User (Sydney)"] --> E3["Edge + data (Sydney)"]
37
+ B1["User (Tokyo)"] --> E1["Edge box + local data (Tokyo)"]
38
+ B2["User (Paris)"] --> E2["Edge box + local data (Paris)"]
39
+ B3["User (Sydney)"] --> E3["Edge box + local data (Sydney)"]
24
40
  E1 <-.->|"replicate"| E2
25
41
  E2 <-.->|"replicate"| E3
26
42
  end
27
43
  ```
28
44
 
29
- The left side has one hot center every user drags a request to and back from, a bottleneck no amount of caching removes. The right side has no center: add a city, add an edge node.
45
+ The left side has one hot center every user drags a request to and back from, plus its dedicated fleet. No amount of caching removes that cost. The right side has no center and no per-app fleet. Add a city, add a shared box, and every tenant on it gets that city for near nothing.
30
46
 
31
- **2. WASM isolation and density.** Each site compiles to its own tiny, [sandboxed](./how-it-works.md#what-build-produces) WASM module that starts fast and cannot touch another tenant's files, memory, or network. Hard per-request limits (a memory cap in the tens of MiB, a **hard compute cap** that cuts off a looping handler, rate limits, and hostile-wasm containment) let one box safely hold many tenants at once, which is what makes compute in many cities affordable instead of a luxury.
47
+ ## Why each mechanism lowers the cost
32
48
 
33
- **3. Allocation-free hot path.** The code that runs on every request wastes nothing: no per-request allocations, and no garbage-collection pauses (so no random latency spikes under load). This earns latency with lean code rather than by overprovisioning hardware to hide slow code, which is a bar toil holds itself to explicitly ([the RSG rubric](./design-principles.md)).
49
+ - **Density** splits the cost of an edge presence across many tenants instead of loading it on one app.
50
+ - **Edge locality** means no origin fleet to run and no cross-planet round trip on every real request.
51
+ - **No dedicated infrastructure** means you scale by adding interchangeable shared nodes, not by standing up a new stack per app.
34
52
 
35
- **4. Stateless tier over a distributed database.** A fresh copy of your handler serves each request and keeps nothing, so every node is interchangeable and you scale out purely by adding more. The data they share lives in [ToilDB](../database/README.md), which distributes **writes** too, not just reads, so there is no single box every write funnels through. The write mechanism and its honest trade-off (eventual consistency) are in [how toil is distributed](./distributed.md).
53
+ Take any one away and a cost comes back. Without density, running near everyone is a luxury again. Without edge locality, you pay for an origin. With a centralized write path, the database caps you and gets overprovisioned to compensate.
36
54
 
37
- **5. Modern transport.** The edge speaks HTTP/3 over QUIC (with graceful fallback to HTTP/2 and HTTP/1.1, plus WebTransport for realtime), and its networking is tuned to keep the connection-level cost of each request low as traffic grows. You configure none of it.
55
+ ## What is real today
38
56
 
39
- The five reinforce each other: take any one away and a bottleneck reappears. No density and edge compute is too expensive to spread; no distributed writes and the database caps you; a wasteful hot path and you are back to buying latency with servers.
57
+ This is the design, not a benchmark. Real throughput and latency depend on your hardware, where your users are, how your data is shaped, and how your handler is written. toil removes the central bottlenecks and keeps per-request cost low. It does not make a slow handler fast, and it does not repeal the speed of light between continents.
40
58
 
41
- ## An honest note on numbers
59
+ Some parts are honestly staged, not already everywhere.
42
60
 
43
- This describes a design, not a benchmark: real throughput and latency depend on your hardware, where your users are, how your data is shaped, and how your handler is written, and toil removes central bottlenecks and keeps per-request cost low without making a slow handler fast or repealing the speed of light between continents.
61
+ - The per-request L1 edge path is live and real. The L2 regional, L3 continental, and L4 global-daemon tiers are opt-in and deployment-gated, not always-on for every app. See the [tiers page](../concepts/tiers.md).
62
+ - ToilDB's home-region write model and its core logic are real and tested. Live multi-cell deployment, meaning WAN routing and the ScyllaDB backing, is configuration-gated, not on by default. The local dev database is a single in-process store. [How toil is distributed](./distributed.md) is honest about what is finished.
44
63
 
45
64
  ## Related
46
65
 
47
66
  - [How toil is distributed](./distributed.md): distributing the writes, the hard problem this rests on.
48
- - [Why toil is built this way (the RSG bar)](./design-principles.md): the efficiency check behind the hot path.
49
67
  - [Compute tiers](../concepts/tiers.md): L1 through L4, and the stateless request model.
50
68
  - [How toil works](./how-it-works.md): the build outputs and the request lifecycle.
51
69
  - [The database (ToilDB)](../database/README.md): families, homes, and eventual consistency.
70
+ - [Why toil is built this way (the RSG bar)](./design-principles.md): the efficiency check behind the hot path.
@@ -1,36 +1,85 @@
1
1
  # The modern stack: what toil gives you that others do not
2
2
 
3
- Most frameworks give you a way to write code and then send you shopping: a database, an auth provider, email, a rate limiter, analytics, a realtime service, a job runner, all wired together and kept in sync by you. toil owns those parts instead: built in, and on from the first line. This page is the catalog of what ships; for how the edge and distribution actually work, see [How toil works](./how-it-works.md) and [How toil is distributed](./distributed.md).
3
+ Most frameworks give you a way to write code, then send you shopping. A database, an auth provider, email, a rate limiter, analytics, a realtime service, a job runner. Each one is its own account, its own bill, and its own SDK, and you keep them all in sync.
4
4
 
5
- ## What is built in
5
+ toil owns those parts instead. They ship in the framework, they are toil's own code, and they run from the first line with no configuration. Nothing third-party sits on your critical path.
6
+
7
+ The good version is the default version. A solo builder gets the same baseline a funded team would rent from ten vendors, with nothing to assemble or babysit. This page is the full catalog. For how the edge and worldwide distribution work, see [How toil works](./how-it-works.md) and [How toil is distributed](./distributed.md).
8
+
9
+ ## Built-in backend features
10
+
11
+ Your TypeScript backend declares what it needs with a decorator or a one-line config flag. toil provides the machinery.
6
12
 
7
13
  | Feature | What it is | Why it matters |
8
14
  | --- | --- | --- |
9
- | Edge compute over HTTP/3 | Frontend and backend both run on servers in many cities, over HTTP/3 with automatic fallback to HTTP/2 or HTTP/1.1. | Code runs next to the user, so there is no slow round trip to one origin. |
10
- | [ToilDB](../database/README.md) | A global database with no connection string and seven families (documents, unique, counter, events, capacity, membership, view). | Distributes writes, not just reads, so a thousand servers can write at once without a single-region bottleneck (trade: eventual consistency). |
11
- | [Post-quantum auth](../auth/README.md) | Password login via `server: { auth: true }`; the password becomes an ML-DSA-44 key in the browser and the server stores only the public key. | The password never crosses the wire in a replayable form, so a breached server yields no usable passwords, and there is no identity vendor to rent. |
12
- | Automatic SRI | A SHA-384 fingerprint on every local script, preload, and stylesheet, plus an import map covering the whole module graph. | Tampered assets simply do not run, even if a CDN or cache hop is compromised. |
13
- | [Email](../services/email.md) | `EmailService.send(...)` or a reusable `EmailTemplate` with `{{placeholder}}` bodies, through a provider you configure once. | Verification codes, resets, and receipts are one call: validated, per-tenant capped, and off the worker while the provider replies. |
15
+ | [Post-quantum auth](../auth/README.md) | Password login via `server: { auth: true }`. The password is stretched (OPRF + Argon2id) into an ML-DSA-44 keypair in the browser; only the public key is sent; login runs ML-KEM-768 mutual auth so the client also verifies the server. | Real post-quantum cryptography (the NIST-standardized algorithms), in about one line. The password never reaches the server in a usable form, so a breached server yields nothing replayable, and there is no identity vendor to rent. |
16
+ | [ToilDB](../database/README.md) | A global database with no connection string and seven purpose-built families. Its differentiator is distributed writes: every key has one home region that orders its writes, while data replicates outward for fast local reads. | Distributes writes, not just reads, so a thousand servers can write at once with no single-region bottleneck. This is the hard part almost nobody does (trade: eventual consistency, a far read can lag a few ms). |
17
+ | [Email](../services/email.md) | `EmailService.send(...)`, or a reusable `EmailTemplate` with `{{placeholder}}` bodies, through a provider you configure once. | Verification codes, resets, and receipts are one validated, per-tenant-capped call, off the worker while the provider replies. |
14
18
  | [Rate limiting](../services/ratelimit.md) | `@ratelimit` on a route, counted at the edge in an exact cross-worker limiter keyed on the caller's network address. | Over-limit clients are rejected before your code runs, blunting brute-force and spam. |
15
- | [Analytics and time series](../services/analytics.md) | The `Analytics` global reads your site's own counters: `self()` for a snapshot, `series(metric, range)` for a graph. | A real usage dashboard with no extra code and no analytics vendor, correct across every edge location. |
16
- | [Realtime streaming](../realtime/README.md) | A `@stream` class with `@connect`/`@message`/`@close`/`@disconnect` hooks, opened from React with `useChannel`; WebTransport in production, WebSocket in dev. | A resident instance stays alive per connection and remembers state next to the user (chat, presence, progress). |
17
- | [Daemons and @derive](../background/README.md) | `@daemon` runs one global background worker on a schedule (interval or cron) with lease-based failover; `@derive` re-runs when its source data changes to refresh a View. | Nightly jobs and rollups run once globally, with no cron server, queue, or leader election to run yourself. |
18
- | [Owned globals](../services/README.md) | No-import cookies (read/set, sign or encrypt), crypto (hash, HMAC, AES, random), time (the edge clock), and environment/secrets. | Your request's small dependencies live in one system, and your compiled program carries no credential. |
19
- | [Toolchain](../cli/README.md) | `toiljs create` scaffolding, a shared ESLint config, Prettier plus a decorator-aware plugin, an editor plugin, one CLI, and `toiljs doctor --fix`. | Set up for you and wired by types, so a server change is a compile error at your desk, not a production bug. |
20
- | LLM-friendly docs | A machine-readable `llms.txt` plus a generated `.toil/docs/` folder and pointer files (`CLAUDE.md`, `AGENTS.md`, editor rules), refreshed on every build. | An assistant reads your current conventions instead of guessing from stale training. |
19
+ | [Analytics](../services/analytics.md) | The `Analytics` global reads your site's own counters: `self()` for a snapshot, `series(metric, range)` for a graph. | A real usage dashboard with no extra code and no analytics vendor. |
20
+ | [Realtime streaming](../realtime/README.md) | A `@stream` class with `@connect` / `@message` / `@close` / `@disconnect` hooks, opened from React with `useChannel`. WebTransport (over QUIC) in production, WebSocket in dev. | A resident instance stays alive per connection and remembers state next to the user: chat, presence, live progress. |
21
+ | [Background jobs (`@daemon`)](../background/daemons.md) | One global background worker on a schedule (interval or cron), with lease-based failover so exactly one instance runs worldwide. | Nightly jobs run once globally, with no cron server, queue, or leader election to run yourself. |
22
+ | [Scheduled jobs (`@scheduled`)](../background/daemons.md) | A method that fires on an interval or cron expression, driven by the same lease so it runs once across the fleet. | Recurring work (cleanup, digests, syncs) without standing up a scheduler. |
23
+ | [Materialized views (`@derive`)](../background/derive.md) | A function that re-runs when its source data changes and writes the result into a View family. | Rollups and denormalized read models stay fresh automatically, so reads are cheap without a hand-rolled pipeline. |
24
+ | [Sessions and cookies](../services/cookies.md) | No-import cookie read/set, signed or encrypted, plus the session layer that backs `@auth`. | Login state and small per-user data without a session store to provision. |
25
+ | [Environment and secrets](../services/environment.md) | A per-tenant environment store for config and secrets, read at the edge, never baked into the shipped WASM. | Your compiled program carries no credential; secrets live in one place, disjoint from public config. |
26
+
27
+ ### The seven ToilDB families
28
+
29
+ One database, seven shapes. Each family is tuned to its own access pattern instead of forced out of a single table model.
21
30
 
22
- ## Built in versus assemble it yourself
31
+ | Family | For |
32
+ | --- | --- |
33
+ | [Documents](../database/documents.md) | General structured records. |
34
+ | [Unique](../database/unique.md) | Uniqueness constraints (one email, one handle). |
35
+ | [Counter](../database/counters.md) | High-throughput increments (views, likes, quotas). |
36
+ | [Events](../database/events.md) | Append-only logs and feeds. |
37
+ | [Membership](../database/membership.md) | Set membership and relationships (who is in what). |
38
+ | [Capacity](../database/capacity.md) | Bounded resources and seat/slot allocation. |
39
+ | [View](../database/views.md) | Read models materialized by `@derive`. |
40
+
41
+ ## Built-in frontend features
42
+
43
+ The React client is Vite-fast and typed end to end. The pieces that usually take a build config, a fetch layer, and an SEO plugin are already wired.
44
+
45
+ | Feature | What it is | Why it matters |
46
+ | --- | --- | --- |
47
+ | [File routing](../frontend/routing.md) | Routes are files under `client/routes/`. The tree is your URL map. | No router config to hand-maintain; add a file, get a route. |
48
+ | [Loaders with revalidation](../frontend/data-fetching.md) | A route `loader` fetches its data before render and revalidates on demand. | Data arrives with the page, not after a client-side waterfall. |
49
+ | [Two rendering paths](../frontend/rendering.md) | Build-time prerender for SEO by default, plus opt-in edge SSR with `export const ssr = true`, both hydrated with `hydrateRoot`. | Static-fast pages where you can, live server rendering where you need it, one codebase. |
50
+ | [Typed `Server` client](../frontend/data-fetching.md) | A generated client (`Server.REST.*`, `Server.Stream.*`, `Server.<service>`) so the browser calls the backend with end-to-end types. | No hand-written fetch and no drift: rename a field on the server and the frontend stops compiling until you fix it. |
51
+ | [Image with LQIP](../frontend/images.md) | A built-in `Image` component with blur / low-quality placeholders and reserved aspect ratio. | Fast, layout-stable images with no CLS and no separate image service. |
52
+ | [Metadata and SEO](../frontend/metadata.md) | Per-route title, description, canonical, and Open Graph (including `og:image`), baked into the served HTML head. | Correct SEO and share cards in view-source, not assembled by JavaScript after load. |
53
+ | [Page search](../frontend/search.md) | A static index of each route's title, description, keywords, and Open Graph, generated at build. | In-app search with no search vendor (see the caveat below). |
54
+ | [SHA-384 SRI](../concepts/security.md) | Subresource Integrity plus importmap integrity on every shipped script, preload, and stylesheet, across the whole module graph. | A tampered asset simply does not run, even if a CDN or cache hop is compromised. |
55
+
56
+ ## toil versus a typical stack
57
+
58
+ Everything above is toil's own code on your critical path. You can inspect it, patch it, and secure it. The table below draws the difference.
23
59
 
24
60
  | Capability | toil (built in, zero setup) | Typical stack (you assemble it) |
25
61
  | --- | --- | --- |
26
- | Edge and transport | Frontend and backend worldwide over HTTP/3 | A separate edge product, often reads-only |
27
62
  | Database | ToilDB: global, distributed writes, seven families | A managed database, usually single-region for writes |
28
63
  | Auth | Post-quantum login; the server holds no password | A rented identity provider or hand-rolled hashing |
29
64
  | Email, rate limiting, analytics | Built-in primitives, one call each | A separate SDK or vendor per capability |
30
- | Realtime and background | `@stream`, `@daemon`, `@derive` | A realtime service plus a cron server, queue, and leader election |
31
- | Asset integrity and toolchain | Automatic SRI, ESLint/Prettier/editor plugins, one CLI | Manual or skipped; configured and maintained by you |
65
+ | Realtime and background | `@stream`, `@daemon`, `@scheduled`, `@derive` | A realtime service plus a cron server, queue, and leader election |
66
+ | Sessions, secrets, cookies | Owned globals, no store to provision | A session store and a secrets manager to run |
67
+ | Frontend integrity and SEO | Automatic SHA-384 SRI, Image/LQIP, metadata, page search | Plugins and services bolted on per concern |
32
68
  | Critical-path ownership | The core is toil's own | A mix of vendors you cannot inspect or fix |
33
69
 
34
- ## Why it is all a default
70
+ Owned means the core of a working app is toil's. It does not mean outside services are banned. You can still call a payment provider or any other API.
71
+
72
+ ## Honest limits
73
+
74
+ toil grades itself on honesty. Read these before you count on anything.
75
+
76
+ - **Distributed writes are built, live multi-cell is config-gated.** The home-region model and its core logic are real and tested. Live multi-region deployment (WAN routing, the ScyllaDB backing) is opt-in, not on by default. The local dev database is a single in-process store. toil is built to distribute writes worldwide. Not every app is running a live global write cluster today.
77
+ - **Analytics is a dev stub locally.** It is real on the edge. The local dev server returns sample data.
78
+ - **Auth secrets ship as dev placeholders.** The session HMAC, OPRF seed, and ML-KEM key are clearly insecure placeholders so `toiljs dev` just works. A real deployment must set its own. Per-tenant auto-generation at domain registration is the plan.
79
+ - **Page search indexes static metadata only.** Routes whose metadata comes from a dynamic `generateMetadata` are not in the index.
80
+
81
+ ## Why these ship by default
82
+
83
+ None of this is an upgrade you unlock later. toil grades itself against [RSG](./design-principles.md), the Resilience and Scale Grade. Its one rule: your grade is your weakest axis, never the average. These built-in parts exist so no single axis quietly caps the whole.
35
84
 
36
- None of this is an upgrade you unlock later. toil grades itself against [RSG](./design-principles.md) (Resilience and Scale Grade), whose one rule is that your grade is your weakest axis, never the average, so these batteries exist to keep any single axis from quietly capping the whole. Where the honest trade fits your project (ToilDB is not general SQL, the server language is a strict TypeScript subset, the catalog is younger than long-established platforms), the built-in stack is the whole point; [Why toil](./why-toil.md) says where it does not.
85
+ The trades are real. ToilDB is not general SQL. The server language is a strict TypeScript subset. The catalog is younger than long-established platforms. Where those trades fit your project, the built-in stack earns its place. [Why toil](./why-toil.md) covers where it does not.
@@ -1,48 +1,64 @@
1
1
  # toil versus other stacks
2
2
 
3
- An honest look at where each stack you already use hits a ceiling, and why toil bets on a different shape. Each of these tools is genuinely good at what it was built for, so the goal is not to crown a winner but to show *where* each one typically caps.
3
+ This page compares toil to the stacks you already use, axis by axis. Every tool below is good at what it was built for. The aim is to be concrete about what you gain and what you give up. toil is younger than all of them, and that shows in a few rows.
4
4
 
5
- We grade with the [RSG rubric](./design-principles.md), whose rule is that a system's grade is its **weakest** axis, never the average. So the useful question is not "what is it great at?" but "what quietly caps it?" For most stacks the answer is the same axis: the **data path** (how and where writes happen), sometimes joined by **dependencies** (how much of the critical path you rent versus own).
5
+ toil trades a large, mature ecosystem for one owned framework. That framework distributes writes and ships fast, safe defaults for free. Whether the trade fits your project is the question this page answers.
6
6
 
7
- RSG is toil's own internal rubric, not an external standard, and every stack below can be configured many ways. The caps described are the *typical* production shape, not a claim that they are unavoidable.
7
+ ## The comparison table
8
8
 
9
- ## Where each stack caps
9
+ | Axis | A typical modern stack | toil |
10
+ | --- | --- | --- |
11
+ | Pieces on the critical path | A dozen rented vendors (host, functions, database, auth, email, queue, cache, analytics, realtime), each its own account, bill, and SDK | One framework you write in; the core services are toil's own, so nothing third-party sits on the critical path |
12
+ | Where writes land | One primary region: reads go global, writes crawl back to that box | Every key has one home region that orders its writes, while data replicates outward for fast local reads (built to distribute; live multi-cell is configuration-gated) |
13
+ | Server runtime | A Node process, container, or VM per app | A small sandboxed WebAssembly module; one edge box safely runs many apps (multi-tenant), which is what makes running near everyone affordable |
14
+ | Client-to-server calls | Hand-written fetch/REST, types drift until something breaks in production | A generated, fully typed `Server` client with no raw fetch: change a field on the server and the frontend stops compiling until you fix it |
15
+ | Auth | Bolt on a provider or roll your own | Post-quantum login (ML-DSA + ML-KEM) built in, enabled in about one line |
16
+ | Getting to production | Assemble CDN, cache, regions, hardened auth, and CI yourself | Zero config: the good version is the default version |
17
+ | Toolchain | A decade of bundler configs, transpiler shims, CommonJS-versus-ESM interop, and `node_modules` churn | Built on modern web tech (React + Vite client, one CLI), far less legacy to fight |
18
+ | Database | Mature SQL: joins, ad-hoc queries, huge tooling | Seven purpose-built families (Documents, Unique, Counter, Events, Membership, Capacity, View): fast and distributed, but not relational |
19
+ | Package ecosystem | The full npm and Node universe | A strict TypeScript subset with built-in globals; no arbitrary npm packages or Node APIs on the server |
20
+ | Integration catalog | Large, mature, well documented | Smaller and younger |
21
+ | Single-region app | Dead simple, nothing to distribute | Distribution you may not need |
10
22
 
11
- | Stack | Great at | Typical binding axis | Why it caps there |
12
- | --- | --- | --- | --- |
13
- | **Next.js / Vercel** | DX, React, global edge reads | data path | Global reads, single-region writes: a sudden write-heavy spike concentrates on one DB box that edge caches and read replicas cannot relieve, while serverless cold starts add latency and per-invocation billing climbs exactly when load peaks |
14
- | **Rails / Django** | Maturity, batteries included | topology / availability / data | Centralized single-region monolith: one place to be near, one place to fail, and one primary every write must reach |
15
- | **Serverless functions** (Lambda, Cloud Functions) | Elastic stateless compute | data path | Distributes compute, not state; the central DB stays the write bottleneck, and a cold-start burst adds latency and cost right when traffic surges |
16
- | **Edge runtimes** (Workers, Deno Deploy) | Code at the edge, near users | data path | Distributes compute beautifully, but the DB you attach is usually single-region (Durable Objects / D1 excepted, below) |
17
- | **BaaS** (Supabase, Firebase) | Fastest to start | dependencies + data path | You rent a managed service you cannot inspect or fix, and writes resolve against a primary |
18
- | **toil** | Owned stack, distributed writes | aims for no single binder | Every key has one home region that serializes its writes; auth, DB, email, and jobs are owned, so the usual caps are designed out (latency and client axes are still yours to earn) |
23
+ The top rows lean toil's way. The bottom rows lean the incumbents' way. toil wins the structural axes: one owned stack, distributed writes, a multi-tenant sandbox, end-to-end types, and built-in modern auth. It concedes the ecosystem axes that maturity buys: SQL, the Node universe, and catalog size.
19
24
 
20
- ## One line each
25
+ ## How toil compares to each stack
21
26
 
22
- - **Next.js / Vercel:** superb reads and DX, but a sudden spike (a viral launch, a flash sale, a timed drop where everyone writes in the same second) lands as a thundering herd on the one write region, so latency, timeouts, and per-invocation cost climb together while edge caching helps only the reads.
23
- - **Rails / Django:** mature and productive, capped by its single-region shape; you can add replicas and standbys to climb, but distributed *writes* are not in the default model.
24
- - **Serverless functions:** great elastic compute, but it is stateless compute in front of a central database, so a write burst still bottlenecks on that store and each cold invocation bills separately.
25
- - **Edge runtimes:** the closest in spirit to toil's compute model, yet edge compute in front of a central database is just a faster front door to the same bottleneck.
26
- - **Cloudflare Durable Objects / D1:** the closest mainstream analog to toil's idea, and credit is due. A Durable Object gives one object a single-writer home that serializes its writes, the same shape as ToilDB's per-key home. The difference is packaging: with the edge-runtime approach you assemble the pieces yourself (runtime, object or DB product, auth, email), whereas toil ships distributed writes, the seven database families, auth, email, streaming, and jobs as one integrated owned stack. Which you prefer is a genuine trade-off.
27
- - **BaaS (Supabase, Firebase):** fastest to start, but the convenience is a managed service on your critical path, and writes still resolve against a primary, so it is **dependency-bound and data-bound**.
27
+ **Next.js / Vercel.** Superb React DX and global edge reads. The ceiling is the write path. Pages cache worldwide, but a write still resolves against one primary region. A comment, an order, a flash-sale click all crawl back to that box. Serverless cold starts add latency and per-invocation cost right when a spike hits. toil keeps a React-first client and moves the write to a home region near the data.
28
28
 
29
- ## Being honest about toil's own limits
29
+ **Rails / Django.** Mature, productive, and batteries included, with a deep hiring pool. If one region suits you, this is a great and boring choice. The default shape is a single-region monolith with one primary that every write must reach. You can add replicas and standbys to scale, but distributed writes are not in the model.
30
30
 
31
- RSG grades toil by the same weakest-link rule, and some axes are not handed to you for free:
31
+ **Serverless functions (Lambda, Cloud Functions).** Elastic, stateless compute that scales to zero. It still sits in front of a central database, so a write burst bottlenecks on that store. Each cold invocation bills and lags on its own.
32
32
 
33
- - **Younger, smaller ecosystem.** Fewer integrations, tutorials, and hosting options than the mature stacks above. If your project is defined by a large existing integration catalog, that gap is real today.
34
- - **The server language is a TypeScript subset.** toilscript compiles a strict subset of TypeScript to WebAssembly: no arbitrary npm packages or Node APIs on the server, built-in globals instead. That is the price of the small, fast, safe sandbox.
35
- - **ToilDB is not SQL.** It is seven purpose-built families, not a relational engine, so heavy ad-hoc joins and existing SQL schemas are not its shape (see the [database overview](../database/README.md)).
36
- - **Some axes you still earn.** RSG measures delivered latency, program performance, and client performance from *your* code. toil removes the structural caps, but it cannot make slow application code fast or a bloated client light.
33
+ **Edge runtimes (Workers, Deno Deploy).** The closest in spirit to toil's compute model: your code runs near users. The catch is the database you attach. It is usually single-region, so edge compute becomes a faster front door to the same central write bottleneck.
37
34
 
38
- ## toil's bet
35
+ Cloudflare Durable Objects and D1 are the closest mainstream analog to toil's idea, and credit is due. A Durable Object gives one object a single-writer home that orders its writes, the same shape as ToilDB's per-key home. The difference is packaging. With the edge-runtime approach you assemble the pieces yourself: runtime, object or database product, auth, email, and realtime. toil ships distributed writes, the seven database families, auth, email, streaming, and background jobs as one owned stack. Which you prefer is a real trade-off.
39
36
 
40
- Every stack above is capped in almost the same place: the write path is one box in one region, or the critical path leans on a service you rent. toil's bet is to refuse both at once, own the whole stack and distribute the writes, so the axes that usually cap a "global" system are designed out and the only limits left are the ones your own code sets.
37
+ **Backend-as-a-service (Supabase, Firebase).** The fastest thing to start with, and often the right call for a prototype. The convenience is a managed service on your critical path that you cannot inspect or patch, and writes still resolve against a primary.
41
38
 
42
- Whether that bet fits *your* project is the honest checklist in [Why toil](./why-toil.md).
39
+ ## What incumbents do better
43
40
 
44
- ## Related
41
+ toil does not win every axis. Some gaps are real today:
42
+
43
+ - **Mature ecosystems.** More tutorials, more answered questions, more hosting options, and more people who already know the tool.
44
+ - **SQL and joins.** If your data is relational and you live in ad-hoc queries and joins, a SQL database is the right tool. ToilDB is seven purpose-built families, not a relational engine (see the [database overview](../database/README.md)).
45
+ - **The Node package universe.** The toil server is a strict TypeScript subset compiled to WebAssembly: no arbitrary npm packages or Node APIs, built-in globals instead. That is the price of the small, fast, multi-tenant sandbox.
46
+ - **Bigger integration catalogs.** toil is younger, so the catalog of ready-made integrations is smaller. If your project is defined by a large existing integration catalog, that gap matters.
47
+ - **Single-region simplicity.** If one region already fits your users, toil's distribution is effort you do not need.
48
+
49
+ None of these are permanent, and the right tool is the one that fits the job in front of you.
50
+
51
+ ## The trade toil makes
52
+
53
+ Most stacks cap in the same place. The write path is one box in one region, or the critical path leans on services you rent and cannot fix. toil refuses both. It owns the whole stack and distributes the writes, so the structural caps are designed out. The limits left are the ones your own code sets.
54
+
55
+ One caveat, to keep the mechanism honest. The home-region model and its core logic are real and tested. Live multi-region deployment is configuration-gated rather than on by default: the WAN routing and the ScyllaDB backing are opt-in, and the local dev database is a single in-process store. Compute works the same way. Your code runs at the edge on every request, while the regional, continental, and global-daemon tiers are opt-in. So the honest claim is that toil is built to distribute writes worldwide and the mechanism is real. It does not mean every app is already running a live global write cluster today.
56
+
57
+ Whether the trade fits your project is the checklist in [Why toil](./why-toil.md).
58
+
59
+ ## Related pages
45
60
 
46
61
  - [Why toil? Who is it for?](./why-toil.md): the problem toil solves and the honest cases where you should not use it.
62
+ - [The modern stack](./modern-stack.md): the full, verified catalog of what is built in.
47
63
  - [How toil is distributed](./distributed.md): the mechanism behind distributed writes (every key's single home region).
48
- - [Why toil is built this way (the RSG bar)](./design-principles.md): the weakest-link rubric this comparison uses.
64
+ - [Why toil is built this way](./design-principles.md): the bar toil grades itself against.
@@ -1,36 +1,44 @@
1
1
  # Why toil? Who is it for?
2
2
 
3
- toil is a full-stack framework: you write a React frontend and a TypeScript backend in one project, and toil runs both (plus a database) close to every user, worldwide.
3
+ toil is a full-stack framework. You write a React frontend and a TypeScript backend in one project, and toil runs both, plus a database, close to every user worldwide.
4
4
 
5
- The thesis in one line: toil is the modern full-stack tech a developer would actually want, AAA-grade from the very first line, and hyper-scalable at the same time. Even a simple pizza site gets top-tier infrastructure with zero setup. Distributed writes are one pillar of that. The modern stack that just works is the heart.
5
+ The thesis is simple. toil is the modern full-stack tooling a developer actually wants: AAA-grade from the first line, and built to scale to the whole planet. Even a simple pizza site gets top-tier infrastructure with zero setup. Distributed writes are one pillar of that. The stack that just works is the core.
6
6
 
7
- ## The problem with today's stacks
7
+ ## The problem with modern stacks
8
8
 
9
- Two problems, really.
9
+ Shipping a good app today means fighting your own infrastructure. It fights back in five ways.
10
10
 
11
- **Read-global, write-central.** Your pages load fast from caches worldwide. But a *write* (a comment, a like, an order) usually travels to one database in one region. A user in Sydney writing to a database in Virginia pays for the round trip. That single region is also a single point of failure.
11
+ **Reads go global, writes go to one region.** Your pages load fast from caches worldwide. A write does not. A comment, a like, or an order has to crawl back to a single database in a single region. A user in Sydney writing to Virginia pays for the whole round trip. That one region is also a single point of failure for everyone.
12
12
 
13
- **The ten-vendor tax.** A typical production stack is stitched from rented services: a frontend host, serverless functions, a managed database, auth, email, a queue, a cache, analytics, realtime. Each is its own account, bill, SDK, and failure mode. You did not set out to be a systems integrator, but the stack hands you the job.
13
+ **You become a systems integrator by accident.** A production stack is a dozen rented services stitched together: a frontend host, serverless functions, a managed database, auth, email, a queue, a cache, analytics, realtime. Each has its own account, bill, SDK, and outage. Every one on your critical path is a black box you cannot inspect, patch, or secure. When it is slow, you are slow. When it is breached, part of you is breached.
14
14
 
15
- And every third-party service on your **critical path** (what must work for a request to succeed) is a black box you cannot inspect, patch, or fully secure. When it is slow, you are slow. When it is breached, part of you is breached.
15
+ **It runs on yesterday's tooling.** The typical stack sits on a decade of legacy: bundler configs, transpiler shims, CommonJS-versus-ESM interop, framework churn, and a `node_modules` folder heavier than the app itself. You fight the toolchain and chase version bumps instead of building. The web platform moved on. The stack did not.
16
16
 
17
- The result: a solo builder and a funded startup hit the *same* wall. Good, safe, fast infrastructure means assembling and babysitting a lot of parts, so most people settle for less.
17
+ **Every layer adds overhead.** Heavy runtimes, slow builds, serverless cold starts, oversized JavaScript in the browser, and a network hop between every service. Each layer adds latency and cost. The user feels it and you debug it.
18
18
 
19
- ## What toil does instead
19
+ **Fast and safe are opt-in, never default.** Good performance and real security are things you assemble by hand: a CDN here, a cache there, careful data fetching, region tuning, hardened auth, current cryptography. Miss a piece and you are slow or exposed. The good version is always extra work, so most people ship the lesser one.
20
20
 
21
- Close the gap, own the pieces, and make the good version the *default* version. Four pillars.
21
+ A solo builder and a funded startup hit the same wall. Top-tier infrastructure means assembling and babysitting a lot of parts, so most settle for less.
22
22
 
23
- ### 1. AAA-grade from the first line
23
+ ## What toil delivers
24
24
 
25
- Top-tier infrastructure on day one, on the smallest project, with zero setup: edge compute (your code runs near users worldwide), one-line post-quantum login, automatic tamper-proofing of your app's code, HTTP/3, and a global database already there.
25
+ Every design decision in toil serves one goal: AAA-grade infrastructure by default, not something you assemble by hand. One framework instead of ten rented vendors. Zero configuration. No distributed-systems or networking expertise required. It works out of the box, quantum-proof login included.
26
26
 
27
- A pizza site and a planet-scale app start from the same baseline. "AAA-grade" is the actual bar toil grades itself against; see [design principles](./design-principles.md).
27
+ Four pillars carry it.
28
28
 
29
- ### 2. Batteries-included, and owned
29
+ ### AAA-grade infrastructure by default
30
30
 
31
- Auth, database, email, rate limiting, analytics, realtime streaming, and background jobs are all built in and are toil's own. Nothing third-party sits on your critical path.
31
+ Top-tier infrastructure on day one, on the smallest project, with zero setup. Your code runs at the edge near users worldwide. A global database is already there. Every shipped asset is tamper-proofed automatically with SHA-384 Subresource Integrity. Login is quantum-proof in about one line.
32
32
 
33
- Because they are one system, the parts already fit. You are not gluing ten SDKs together and praying they agree. Full catalog: [The modern stack](./modern-stack.md).
33
+ That login is real post-quantum cryptography. Your password is stretched into a signing key on your device and never reaches the server in a usable form. The handshake uses ML-DSA and ML-KEM, the NIST-standardized algorithms meant to survive a quantum computer. Most stacks bolt current crypto on by hand, if at all. Here it is the default.
34
+
35
+ A pizza site and a planet-scale app start from the same baseline. AAA-grade is the actual bar toil grades itself against. See [design principles](./design-principles.md).
36
+
37
+ ### Everything built in, and owned
38
+
39
+ Auth, database, email, rate limiting, analytics, realtime streaming, and background jobs are all built in, and all toil's own. Nothing third-party sits on your critical path.
40
+
41
+ Because they are one system, the parts already fit. You are not gluing ten SDKs together and hoping they agree. Full catalog: [The modern stack](./modern-stack.md).
34
42
 
35
43
  ```mermaid
36
44
  flowchart TB
@@ -52,19 +60,19 @@ flowchart TB
52
60
  end
53
61
  ```
54
62
 
55
- Honest boundary: "owned" means the *core* of a working app is toil's, not that outside services are banned. Call a payment provider or another API and you still can.
63
+ Honest boundary: owned means the core of a working app is toil's, not that outside services are banned. Call a payment provider or another API and you still can.
56
64
 
57
- ### 3. A modern DX that just works
65
+ ### Modern tooling that just works
58
66
 
59
- TypeScript end to end, one repo, one deploy, wired by types: change a field on the server and the frontend stops compiling until you fix it (a compile error at your desk, not a production bug).
67
+ Built on today's web platform, not a decade of legacy. TypeScript end to end, one repo, one deploy, wired by types. Change a field on the server and the frontend stops compiling until you fix it. The bug surfaces at your desk as a compile error, not in production.
60
68
 
61
- The toolchain is set up for you: ESLint, Prettier (with a plugin for toil's decorators), an editor plugin, one CLI, and a `doctor` that fixes common problems in place. The docs are even LLM-friendly, so an AI assistant reads your current conventions instead of guessing. More in [The modern stack](./modern-stack.md).
69
+ The toolchain is set up for you: ESLint, Prettier with a plugin for toil's decorators, an editor plugin, one CLI, and a `doctor` command that fixes common problems in place. The docs are LLM-friendly too, so an AI assistant reads your current conventions instead of guessing. More in [The modern stack](./modern-stack.md).
62
70
 
63
- ### 4. Hyper-scalable and distributed (one pillar, not the whole story)
71
+ ### Hyper-scale and distributed writes
64
72
 
65
- Your backend compiles to a tiny sandboxed **WebAssembly** module (a compact, locked-down binary that runs at near-native speed), so one edge box safely runs many apps, which makes running near everyone affordable.
73
+ Your backend compiles to a tiny sandboxed **WebAssembly** module, a compact locked-down binary that runs at near-native speed. That is modern tech, not a heavyweight legacy runtime. One edge box safely runs many apps, so running near everyone stays affordable.
66
74
 
67
- And the database, **ToilDB**, distributes the *writes*, not just the reads: every key has one **home** region that orders its writes, while data replicates outward for fast local reads. Distributing writes is the hard part almost nobody does. The trade is eventual consistency: a far read can lag a few milliseconds. See [How toil works](./how-it-works.md) and [How toil is distributed](./distributed.md).
75
+ The database, **ToilDB**, distributes the writes, not just the reads. Every key has one **home** region that orders its writes, while data replicates outward for fast local reads. Distributing writes is the hard part almost nobody does. toil is built to do it worldwide, and the mechanism is real and tested. Live multi-region deployment is configuration-gated rather than on by default. Once it is on, a far read can lag a few milliseconds: the eventual-consistency trade. See [How toil works](./how-it-works.md) and [How toil is distributed](./distributed.md).
68
76
 
69
77
  ## Who it is for
70
78
 
@@ -73,16 +81,16 @@ And the database, **ToilDB**, distributes the *writes*, not just the reads: ever
73
81
  - **Global apps:** logic and data near users on every continent.
74
82
  - **Realtime apps:** chat, presence, and live cursors on built-in streaming, not a bolted-on vendor.
75
83
 
76
- Same install for the smallest project and the largest. You grow into the scale; you do not rebuild to reach it.
84
+ Same install for the smallest project and the largest. You grow into the scale. You do not rebuild to reach it.
77
85
 
78
86
  ## When not to use toil
79
87
 
80
88
  - **You need SQL or heavy joins.** ToilDB is seven purpose-built families, not a general SQL engine. See the [database overview](../database/README.md).
81
- - **You lean on the Node ecosystem.** The server is a strict TypeScript subset compiled to WebAssembly: no arbitrary npm packages, no Node APIs, built-in globals instead.
89
+ - **You lean on the Node ecosystem.** The server is a strict TypeScript subset compiled to WebAssembly. No arbitrary npm packages, no Node APIs, built-in globals instead.
82
90
  - **You are happy single-region and simple.** If one region already fits, toil's distribution is effort you do not need.
83
91
  - **You need a big integration catalog today.** toil is younger, and that catalog is smaller.
84
92
 
85
- None of these are permanent, and the right tool is the one that fits the job in front of you.
93
+ None of these are permanent. The right tool is the one that fits the job in front of you.
86
94
 
87
95
  ## Related
88
96
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "toiljs",
3
3
  "type": "module",
4
- "version": "0.0.102",
4
+ "version": "0.0.104",
5
5
  "author": "Dacely",
6
6
  "description": "The modern React framework: a file-based React frontend and a ToilScript-compiled WebAssembly backend.",
7
7
  "repository": {