Compare/vs Web frameworks

Keep your frontend. Mandala is the backend.

“Web framework” covers two different jobs. One draws pages. The other holds the data, the rules and the API behind them. Mandala has no wish to draw your pages. Its goal is to replace the second job entirely. It does a good part of that today, and this page says exactly which part.

Checked 12 October 2026

You keep Your frontend framework

Next.js, Astro, or the view layer of whatever you use. Pages, design, URLs, search engines, the customer’s experience.

  • Pages and layouts
  • Design
  • SEO
  • Checkout flow
signed commands⇄generated API
Mandala replaces The backend

What you would otherwise write in Rails, Django, Laravel or Express, or rent from a backend service.

  • Data model
  • Rules and permissions
  • API
  • History and audit
  • Search
  • Background work
  • Sign-in for your users · roadmap
  • Email and PDF · built, not released
  • SDKs · roadmap
01 · First, what they do well

Two kinds of framework.

The first two are where your pages live, and Mandala is meant to sit behind them. The other four are complete backends, proven over many years, and they are what Mandala sets out to replace.

Frontend: you keep these
Next.jsVercel · MIT · version 16

React with routing, server rendering, static generation and caching built in. Very strong for public, designed, search-friendly sites. It brings no data layer, sign-in or jobs of its own, which is the gap a backend fills.

AstroMIT

Content-first sites that ship little JavaScript, with islands of interactivity where needed. The storefront that runs on Mandala’s contracts today is an Astro site.

Backend: what Mandala aims to replace
Ruby on RailsRails core team · MIT · version 8.1

One framework for a whole product: data layer, jobs, cache, realtime updates, a sign-in generator, and deployment to your own server set up from the start.

DjangoDjango Software Foundation · BSD · 6.1, with 5.2 LTS

Models, migrations, sign-in, permissions and an admin generated from your models. Long support windows and a careful release process.

LaravelLaravel · MIT · version 13

A complete PHP framework: data layer, queues, policies, websockets, and first-party hosting and tools around it.

ExpressOpenJS Foundation · MIT · version 5

Routing and middleware for Node, and nothing you didn’t ask for. A thin, well-understood base for an API.

Hosted backends such as Supabase and Firebase are the other thing people use for this job. They have their own page: Mandala vs backend services.

02 · The real difference

You write the rule. You don’t write the backend.

In a backend framework, one business rule ends up in several places: a migration, a model validation, a controller, a permission policy, an API serializer, and an audit library you added later. Keeping them in step is the job.

In Mandala the contract on the right is the only place the rule lives. Storage, the check, the lifecycle, the API and the history all come from it. Your frontend calls the API; it never re-implements the rule.

The API is generated and served today

REST with an OpenAPI description, GraphQL with queries and mutations, and gRPC, per contract. Nothing is exposed unless the contract says api public or api authenticated.

The caller signs today

A command carries its caller’s own signature, so the history says who did it, not “the web server”.

History is not an add-on today

None of these frameworks keeps an audit trail in its core; each has well-known libraries for it. Here there is nothing to add.

com.planetexpress.deliveryv3 · DHL
# Nothing ships to the Moon, or over 200 units,# without a second person confirming (Leela).action Ship()    authorize dhl    validate        state.paid or state.credit_terms        state.crates_checked == state.crates        state.status == Requested or state.status == Confirmed        state.status == Confirmed or state.units <= 200        state.status == Confirmed or state.destination != "Moon"    apply        state.status = Shipped
The whole contract (65 lines)
aggregate Delivery    state        public customer: Text(len=200)        public destination: Text(len=100)        public units: Int = 0        public crates: Int = 0        public crates_checked: Int = 0        public paid: Bool = false        public credit_terms: Bool = false        public requested_by: Identity        public confirmed_by: Identity        public status: Enum(New, Requested, Confirmed, Shipped) = New action Request(customer: Text(len=200), destination: Text(len=100), units: Int, crates: Int, credit_terms: Bool)    authorize dhl    validate        state.status == New        units > 0        crates > 0    apply        state.customer = customer        state.destination = destination        state.units = units        state.crates = crates        state.credit_terms = credit_terms        state.requested_by = context.signer        state.status = Requested action CheckCrate()    authorize dhl    validate        state.status == Requested        state.crates_checked < state.crates    apply        state.crates_checked = state.crates_checked + 1 action Confirm()    authorize dhl    validate        state.status == Requested        context.signer != state.requested_by    apply        state.confirmed_by = context.signer        state.status = Confirmed action Pay()    authorize dhl    validate        state.status != New        state.paid == false    apply        state.paid = true # Nothing ships to the Moon, or over 200 units,# without a second person confirming (Leela).action Ship()    authorize dhl    validate        state.paid or state.credit_terms        state.crates_checked == state.crates        state.status == Requested or state.status == Confirmed        state.status == Confirmed or state.units <= 200        state.status == Confirmed or state.destination != "Moon"    apply        state.status = Shipped

Real DHL, exactly as it runs: this contract compiles. Every action is checked against it before it happens, for people and AI alike.

Your frontend sendsDoes
POST /v1/{tenant}/{namespace}/actions/{Action}A signed command
POST /v1/{tenant}/{namespace}/queries/{Query}A declared query
POST /v1/{tenant}/{namespace}/graphqlEither, as GraphQL
03 · What exists today

A shop, with an Astro front and contracts behind.

This is not a plan. In the repository there is a storefront whose pages are Astro and whose whole backend is seven DHL contracts, served by the engine’s generated API on three voters. Astro owns the HTML, the layouts and the SEO. It holds no business rule.

What runs on contracts today, in a preview

The catalogue, a visitor’s cart, the quote, and checkout to a durable order with stock reserved from the right lots. Prices and totals are computed by the contracts, not by the page.

Visitors sign their own commands today, in a preview

A guest’s browser makes a key, the store grants it the right to buy, and every cart action is signed by that visitor.

A real grocer is moving onto it in progress

An online grocer’s existing Astro site now reads its pages, catalogue and guest basket from contracts in a preview. Its checkout, orders and customer accounts are not connected yet and still run on the system it had.

Plainly: these are previews on a private network, not shops taking money. Payments and delivery are not connected. The client the storefront uses is a small hand-written one, not an SDK.

The storefront preview · who does whatin the repository
pages, layouts, SEOAstro
catalogue, cart, quote, order7 DHL contracts
APIgenerated by the engine
writes agreed by3 voters
visitor identitya key in the browser, granted by the store
totals and stockcomputed by contracts
payments, deliverynot connected
statuspreview on a private network

Its test flow opens a cart, adds two lines, quotes them, checks out, and verifies a durable order with a total computed by DHL. It never inserts an order directly.

04 · The whole job

What a backend does, and where Mandala is.

Replacing the backend is the goal. This is the list of what a backend has to do, with where each part stands, read from the code and not from the plan.

works todaybuilt, not releaseddesignedon the roadmapnot planned
A backend mustStatusExactly
Model and validate dataworks todayTyped state, actions and validation in a contract, checked before every write.
Change the schemaworks todayA new version names the one it upgrades from and how fields move. Records are upgraded one by one, each by a signed action; there is no bulk migration.
Enforce business rulesworks todayThe same check for every caller, with refusals that name the rule.
Decide who may do whatworks today
designed
Delegation with a scope and an end date works today. Roles as tags, and decisions that need several people, are designed.
Serve an APIworks todayREST, GraphQL (queries and mutations) and gRPC, generated per contract and served by the engine, with bearer or session credentials. Inside the Workspace the same API sits behind the owner’s sign-in, so an outside application talks to the App server.
Keep history and auditworks todayEvery accepted change is a signed fact. Refusals are recorded too.
Searchworks today
built, not released
Ranked text search from a query works today. Indexed text, vector, graph, time-series and geo search are built on a branch.
Run background workworks today
on the roadmap
Mandala’s own background work is durable and survives restarts. Schedules and queues that a contract declares for itself are on the roadmap.
Send email, make PDFsbuilt, not releasedA contract can declare an email or a PDF document as an effect of an action. The engine has the durable outbox, the retries and the signed receipts. It is not yet switched on in Mandala.
Call webhooks, send SMS, take paymentsdesignedNamed as the next kinds of effect. None is built in the engine.
Use any connector from a ruleon the roadmapToday connectors serve the accomplice and background jobs. No contract can call one yet. The aim is that any connector is usable from DHL.
Run workflows with human stepsworks today
in progress
Steps that wait for a person’s decision, review or approval work in Projects. A visual editor for them is in progress.
Push live updatesdesignedLive queries, where a screen’s answer changes as the data does. Nothing is built; the API has no subscriptions.
Sign your users inon the roadmapOAuth, email and password, and sessions for an application’s own users are not built. Today: passkeys for the owner, and guest sessions in the storefront preview.
Give your frontend an SDKon the roadmapSDKs for Next.js and Astro, and typed clients generated from contracts, do not exist yet. Today you call the API yourself.
Store and deliver fileson the roadmapThere is no file type in a contract and no public file delivery. The storefront preview serves images from its own image service.
Face the public interneton the roadmapToday: public and authenticated operations, a connection cap, a body limit and deadlines. No per-caller rate limits, API keys or abuse protection.
Separate dev, staging and productionpartly today
on the roadmap
You can try a contract on a throwaway node, preview an action, and dry-run an effect. Nothing promotes contracts or data between environments.
Serve many tenantsworks today
not planned
The engine isolates tenants, each with its own keys, actors and contracts. In Mandala a tenant is a person or a business on your own node. Signing up tenants and billing them, as a hosted service would, is not planned.
05 · Where Mandala is behind

Said plainly.

Everything in the table that isn’t green

A Rails or Django application signs users in, sends mail, takes payments, stores files and runs scheduled jobs today. Mandala does not, yet.

Proven under public traffic

These frameworks carry very large public sites. Mandala’s API has run previews. Nobody has leaned on it from the open internet.

Ecosystem

Payments, maps, single sign-on, search services: a framework has a maintained package for each. Mandala has a short list of connectors and an SDK to write more.

People

You can hire a Rails or Django developer this month. Nobody has DHL on their CV yet. The language is small and the accomplice writes it, but that is the truth today.

Maturity

Published support windows, security teams, years of patch releases. Mandala is young and moving fast.

Mira · 10:12
Shipping 120 crates of waffle irons for Lumon to the Moon.
Refused · rule 5 of Ship

Nothing goes to the Moon until a second person confirms it. I’ve asked Leela.

state.status == Confirmed or state.destination != "Moon"
Waiting for Leelaexplain · com.planetexpress.delivery
06 · Which one

Choose honestly.

The pairing Mandala is built for is your frontend framework in front and Mandala behind it. Whether you can take that pairing today depends on what your application needs from the table above.

Choose a framework’s own backend if…

  • You need to be in production this quarter with customer sign-in and payments.
  • You need a mature ecosystem: a package for every service, and answers for every error.
  • Your team knows Rails, Django or Laravel. That is worth a great deal.
  • You expect heavy public traffic and need a stack that has carried it before.

Choose Mandala as the backend if…

  • The hard part of your application is its rules: records, steps, approvals, who may do what.
  • You need the history of every change, signed, without building it.
  • You want an AI to work in the application safely, under the same rules as people.
  • Your users are few and known today, such as a team’s internal tool, and you can wait for public sign-in.

In between, there is a transitional path that an online grocer is taking now: keep the existing backend for sign-in, payments and orders, and move one part at a time behind contracts, starting with the catalogue and the cart. For developers · Mandala vs backend services · Rules, not code

We checked every statement about other products on 12 October 2026, against their own sites, documentation and repositories where we could. Products change. If something here is wrong or out of date, write to hello@getmandala.org and we’ll correct it.

More comparisonsSee them together