The app backend where a feature is defined once.
BlitzGraph models teams, roles, and content as one graph with one typed JSON API. Reads, writes, search, and the queries your agent composes follow a single definition — not a schema, a policy layer, server functions, generated types, and screens that each hold a copy of the rule.
// The team screen: members + active projects, nested { "$kinds": "Team", "$filter": { "name": "Acme" }, "$fields": [ "name", { "$expand": "members", "$fields": ["name", "email"], "$limit": 20 }, { "$expand": "projects", "$filter": { "active": true }, "$sort": "-$created_at", "$limit": 10, "$fields": ["title", "status"] } ] }
The sync tax
One product rule. Five places it lives.
On a table-based stack, a feature is a migration, a policy, a server function, a generated type, and a screen — artifacts that only work while they agree. BlitzGraph collapses them into a schema the database enforces.
Ship a teams feature
On a table stack
Users, teams, memberships, invites: four tables, foreign keys both ways, a join for every read, and an API shape you assemble by hand.
On BlitzGraph
Team, User, and Membership are kinds. Every relationship is queryable from both sides, and the database enforces cardinality and delete behavior.
Render the workspace screen
On a table stack
Three round trips or a hand-tuned join with N+1 traps, then client code to stitch members, projects, and owners back together.
On BlitzGraph
One request. $expand returns the team with members and active projects nested, filtered, sorted, and paginated at each level.
Add search
On a table stack
Bolt on Algolia or tune tsvector, keep it in sync on every write, then re-fetch context around each hit before you can render it.
On BlitzGraph
$search runs in the engine: BM25 relevance, per-field boosts, typo tolerance. Hits are units, so you expand their relationships in the same query.
Let an agent touch the backend
On a table stack
The agent writes SQL, policies, and server functions across the repo — free-form code reviewers verify by hand, and one missing policy ships a data leak.
On BlitzGraph
Agents read the schema over MCP and send typed JSON operations. Malformed shapes are rejected, and experiments run in an isolated subspace.
What's in the box
A backend, not a kit of parts.
General-purpose platforms hand you excellent primitives and leave the assembly to you. These six jobs ship assembled.
Relationships with rules
Roles are typed and bidirectional, with cardinality and delete behavior — cascade, restrict, unlink — enforced by the engine. No orphaned rows, no cleanup triggers.
One query per screen
$expand walks the graph and returns nested, filtered, sorted results at every depth. The response shape is the screen shape.
Logic that travels with the data
Computed fields, validations, and hooks live in the schema, so total = price * qty holds in every write path — including the ones an agent adds later.
Entities that wear many hats
A unit can be User, Admin, and Author at once. Composition instead of flag columns, enum types, or single-table-inheritance workarounds.
Search included
BM25 full-text search with per-field boosts and typo tolerance, indexed as you write. No sidecar service to deploy or keep in sync.
Sandboxes for experiments
Subspaces are isolated areas of the same backend. Let an import or an agent run wild in one; production data never notices.
Writes
Mutations shaped like features, not rows.
An onboarding flow that creates the user profile, team, and first project is one atomic batch. References resolve inside it, cardinality is validated on the final state, and schema hooks run before commit — the same guarantees whether the request came from your code or your agent.
// User + team + first project, one request [ { "$setKinds": ["User"], "$var": "_:ana", "name": "Ana", "email": "[email protected]" }, { "$setKinds": ["Team"], "name": "Acme", "members": "_:ana", "projects": [ { "$setKinds": ["Task"], "title": "Launch" } ] } ]
// honest comparison
Where each side wins.
Supabase, Convex, and Firebase are excellent platforms — the comparison is here because it's the decision you're actually making. This is the honest version, losses included.
Supabase · Convex · Firebase
General-purpose BaaS
Managed database, auth, storage, and functions. Unbeatable time-to-CRUD and mature ecosystems; relationship rules are spread across database, authorization, and application layers as the product grows.
Home turf: mature auth, storage, and years of production hardening get a standard app live fast.
Roles and nested data mean join tables, policies, server functions, and client types that only work while they agree.
Agents generate SQL strings, policies, or server functions — free-form code that reviewers verify by hand.
Agent-native graph backend
BlitzGraph
The relationship layer is the database: typed roles, nested reads, search, and logic in one schema — behind an API agents compose correctly.
The honest boundary: BlitzGraph authenticates dashboard users and agents; public-app user sign-in is not yet a built-in feature. You get the data layer, Studio, and an instant HTTP API.
One schema defines the feature: both directions queryable, integrity enforced, screens read in one request.
Agents read the schema and send typed JSON the engine validates — staged in a subspace production never sees.
Trade-offs
When they're still the right call.
Pick Supabase, Convex, or Firebase when
- You need public-app user sign-in and session management out of the box today
- You need realtime subscriptions on day one
- Open source or self-hosting is a requirement
- You want a decade of Stack Overflow answers
Pick BlitzGraph when
- The product is teams, roles, and content — a graph wearing a table costume
- You want one definition instead of five synchronized layers
- Agents write a meaningful share of your backend
- Search and integrity should be the database’s job
Public beta, free tier, no card required. Your graph exports as JSON whenever you ask.
Start with one feature
Port the screen with the most glue.
Take the one that needs three queries and a diagram to explain. Model it in the playground — if it doesn't collapse into one schema and one query, walk away.