dafny-replay apps talk to the cloud through a thin abstraction layer rather than directly importing a provider SDK. This separation keeps your React components, Dafny dispatch logic, and effect state machine identical across deployments — only the adapter file changes. The same application ships against Supabase for managed infrastructure or Cloudflare Workers for a lower-cost, bring-your-own setup.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/metareflection/dafny-replay/llms.txt
Use this file to discover all available pages before exploring further.
Directory structure
Every app that supports multiple backends has asrc/backend/ directory:
index.ts reads the VITE_BACKEND environment variable at build time and exports the appropriate implementation as backend:
Switching backends
SetVITE_BACKEND in your .env file before building or running the dev server:
The Backend interface
All providers implement the sameBackend interface. The three generic sections — auth, dispatch, and realtime — are identical in shape across all backends:
DispatchResult
The dispatch method returns one of three statuses:accepted— the action was valid and persisted;versionandstatereflect the new server state.rejected— the Dafny domain checker refused the action (invariant violation);errorexplains why.conflict— another writer updated the entity between your read and write; the client should rebase and retry.
Using the backend in React hooks
Frontend code imports frombackend/index.ts and remains agnostic to which provider is active:
@supabase/supabase-js or call fetch directly — that responsibility belongs entirely to the adapter.
Provider comparison
The table below shows what each provider brings and what stays the same regardless of choice:| Component | Supabase | Cloudflare |
|---|---|---|
| Database | PostgreSQL + RLS | D1 (SQLite) |
| Server functions | Edge Functions (Deno) | Workers (JavaScript) |
| Realtime | postgres_changes | Durable Objects (WebSocket) |
| Auth | Supabase Auth (OAuth) | Simple JWT |
| Access control | Database-level RLS | Application-level checks |
What stays the same
Changing backends does not touch any of the following:- Dafny-compiled dispatch logic — pure JavaScript, runs identically in any environment
- Effect state machine — client-side verified state, backend-agnostic
- React components — all backend calls go through the abstraction
- Domain model and proofs — Dafny source and compiled output are unchanged
Both backends run the same compiled Dafny code server-side. The dispatch logic is not re-implemented per provider — the same
.cjs bundle is imported into the Supabase Edge Function (Deno) or the Cloudflare Worker (V8), with a provider-specific build flag (--deno or --cloudflare) to handle module format differences.Adding a new backend
To add a third provider:- Create
src/backend/newbackend.tsimplementing theBackendinterface. - Update
src/backend/index.tsto handle the new value:
Explore the backends
Supabase backend
Managed auth, PostgreSQL with RLS, built-in realtime, and Deno Edge Functions. Batteries included.
Cloudflare backend
D1 SQLite, Workers, Durable Objects for WebSocket realtime, and custom JWT auth. Lower cost.