This is the short version: what Nineveh does, the one idea everything rests on, and where to go next. It takes about five minutes.
These pages describe the hosted service at nineveh.dev, where the infrastructure is ours. Nineveh is also open source, and running it yourself is a supported path. Everything here works the same either way; only the operating differs.
What you get
Point Nineveh at a contract address. It reads that contract's activity from the chain and folds it into tables you define. Those tables are served three ways:
- a REST API over every table, with filtering, ordering and paging
- a change feed that pushes every row change as it happens
- webhooks, signed, to a URL of yours
Two things decide what you get: which of the contract's data you follow, and what each record changes. You pick the first in Studio, off a list it reads from the chain. The second is yours to write — it is the part no tool can guess, and it's where the time goes. Nineveh does the rest.
Why this exists
Aptos gives you point reads: one resource at one address, one view function, one table item by key. That is all the chain itself can answer.
It cannot answer how much volume did this market do today, or show me every open position, or what changed since I last looked. Those questions need the contract's history folded into shape, and on-chain storage costs gas, so contracts deliberately don't keep it. The shape of your app's data lives in events and resource changes: a stream of things that happened, not a table you can query.
Nineveh is the thing that turns that stream into tables.
The one idea
Everything else follows from this, so it's worth a minute:
chain → records → reducers → state tables → your app
The chain is the input. Records are what arrived, the events and resource writes your project follows. Reducers fold those records into state tables. Your app reads the tables.
Four things follow, and each one saves you a surprise later:
State is derived, not written. There is no POST /rows. Every row exists because a
reducer put it there. If a number looks wrong, the reducer is wrong. Nothing else can
have touched it.
Reducers are deterministic. No clock, no randomness, no network calls. The same records always produce the same tables. That is what makes the next two possible.
Your records are kept. Change a reducer and Nineveh rebuilds from its own stored records rather than re-reading the chain: minutes, instead of another backfill. Editing a rule is cheap.
Aptos finalises. Committed transactions never reorg, so there is no rewind logic and no "wait for N confirmations". A version cursor is the whole safety story.
What to read next
In order, if you're new:
- Your first backend: publish a contract, point Nineveh at it, drive it from the Aptos CLI, and query what comes out. Start here; everything else makes more sense after it. Half an hour, and it needs the Aptos CLI and a GitHub account.
- Studio: the dashboard, surface by surface — and the vocabulary, since the words are the model. Read it if you'd rather click than write YAML.
- Reducers: how to say what your tables hold. This is the part you'll spend your time in.
- Reading your data: the REST API, the change feed, webhooks.
- Reading from React: the same, from an app — the hooks, and generated
types for your own tables.
npm create nineveh-appif you want rows on a screen before you read anything. - Running a project: changing it, what a rebuild costs, limits, and what to do when something looks wrong.
And if you are weighing this against writing it yourself: What you'd build instead is the same backend done by hand, step by step, including the parts that only bite later.
Two references, for when you need a specific answer:
- Configuration: every key in
nineveh.yaml, the file Studio writes as you add sources, tables and webhooks. - Expressions: the small language reducer values are written in.
Stuck on something, or it did something you didn't expect? There's a Telegram group — that's the fastest way to reach us.
And if you'd rather run it yourself: Running Nineveh yourself covers building it, the CLI, the control plane, and what you take on as the operator.
What Nineveh is not
Worth knowing now, so you don't design around something that isn't there.
It is not a general backend. Your tables are a read-only projection of the chain. There are no writable app tables, no user accounts, no row-level security. If you need those, you need them somewhere else.
It does not do live aggregate queries. You can subscribe to a table or a row and be told when it changes. You cannot subscribe to "the top ten by volume" and have Nineveh keep the answer correct as trades arrive. Compute aggregates in your reducers instead, into a table, and subscribe to that.
It does not replace Aptos' own indexer for generic data. Token balances, NFTs and name lookups are already served by the hosted Indexer API. Nineveh is for state that is specific to your contract.