React API Stack — alpha
A clean frontend. A powerful backend.
Write a plain TypeScript class, pass it to a hook, and you've got your whole data layer — fully typed and live. Underneath, a fast serverless backend quietly handles storage and scaling for you. Nothing to generate, nothing extra to run.
$ curl -fsSL https://reactapistack.com/setup.sh | sh
copy
You write
entities/airports.ts
ts · copy
1
import
{ MaxLength, Unique }
from
"rastack/db"
;
2
3
export class
Airport
{
4
code
!:
string
&
Unique
&
MaxLength<3>
;
5
name
!:
string
;
6
}
nothing to run — your dev server compiles the schema on save
You get
app/airports.tsx — no codegen
tsx · copy
1
const
airports
=
useData
(
Airport
);
// typed end-to-end
2
<
DataTable
query
={
airports
} />
3
const
form
=
useForm
(
Airport
, {
id
});
See the pipeline ↓
01 / The surface
TypeScript
·
React
·
TanStack Query
·
OpenAPI
·
Rust
·
Apache Iceberg
·
Parquet
·
Amazon S3
·
AWS Lambda
·
WebAssembly
·
TypeScript
·
React
·
TanStack Query
·
OpenAPI
·
Rust
·
Apache Iceberg
·
Parquet
·
Amazon S3
·
AWS Lambda
·
WebAssembly
·
TypeScript
·
React
·
TanStack Query
·
OpenAPI
·
Rust
·
Apache Iceberg
·
Parquet
·
Amazon S3
·
AWS Lambda
·
WebAssembly
·
02 / The pipeline
One class becomes the whole stack.
Curious what happens after you save? Here's the tour. Write a class once, and the data layer, the storage and the deployment all follow from that one file — you don't have to wire any of it together yourself.
01
Write the classes
Plain TypeScript classes are the single source of truth — fields, constraints and relations live in the type system. No DSL.
02
The contract compiles itself
No compile command, no schema wiring. The rastack/plugin bundler plugin (or rastack dev) derives the manifest from your classes on every save and registers it before the app boots; CI emits the OpenAPI contract on deploy. Types never come from this step — they flow from the class as-is.
03
The engine stores it
A stateless Rust API persists every model as an Apache Iceberg table on object storage.
04
Ship it serverless
Rust on Lambda, S3 as the system of record. Scale to zero, scale to millions.
Read the full guide →
entities/airports.ts
ts · copy
1
import
{ MaxLength, Unique }
from
"rastack/db"
;
2
3
export class
Airport
{
4
code
!:
string
&
Unique
&
MaxLength<3>
;
5
name
!:
string
;
6
}
7
8
export class
Terminal
{
9
airport
!:
Airport
;
// foreign key — inferred
10
label
!:
string
;
11
}
03 / The frontend
A frontend that feels effortless.
The part you touch every day is built to feel good: clean, typed and predictable. Your classes already describe your data — we just hand that straight to React, so everything stays in sync on its own.
01
Pass your type, get your data
No generated hooks, no generated types, no compile command. useData(Airport) and useForm(Airport) are typed by your own declaration, and the schema recompiles itself inside your dev server on every save.
02
Zero drift
Change a class and the schema recompiles on save. The call sites that no longer typecheck are exactly the ones that need your attention.
03
Hooks you'll love
Query keys, invalidation, suspense and mutations come for free with end-to-end inference — two hooks, clean ergonomics, no boilerplate.
04
Built-in guardrails
Spell out the steps something can move through once — draft, booked, boarded — and every form and import follows them automatically. Typos get caught by the types: form.transition("board") works, "explode" won't.
05
Local-first sync
Opt an entity into local-first replication and the same hooks go store-backed — an offline cache and a long-poll changefeed alongside plain REST.
06
Works with what you use
Vite, Next.js, Remix, Expo — take your pick. No lock-in, and nothing hidden: it's just two hooks and a schema file you can open and read yourself.
04 / The engine
A backend that runs itself.
The nice part: you mostly don't have to think about it. Your data lives as plain files in cloud storage, and the backend only wakes up when there's an actual request to handle — so there's no database server to run, patch, or pay for while it sits idle.
01
Object storage is the database
Every model persists as Apache Iceberg / Parquet on S3 — the system of record, at 11-nines durability and a fraction of the cost.
02
Only runs when needed
A fast Rust API runs on AWS Lambda. When traffic stops, nothing runs — and you only pay for the storage that's sitting there.
03
Time travel built in
Iceberg snapshots give every table a full history. Query data as of any point in time — audit trails and recovery for free.
04
No glue code to write
Reading, writing, validation and access control all come from your classes — there's no per-model backend code for you to write or maintain.
terminal
bash · copy
1
# the database IS object storage
2
rastack
init
# stand up the serverless backend
3
rastack
deploy
# ship the Rust API to Lambda
4
5
# S3 warehouse · Iceberg + Parquet · no server DB
S3 capacity
→ 0
Scale to zero
11×9
Durability
05 / Get started
Up and running, top to bottom.
Define your data once, then pass your classes straight to the React hooks. Install the CLI with a single command — no clone, no config — the way you'd install Poetry or rustup. Fair warning: it's still alpha, so expect some rough edges and breaking changes along the way.
macOS & Linux
Installs the `rastack` CLI into ~/.rastack — no sudo.
terminal
sh · copy
1
curl
-fsSL
https://reactapistack.com/setup.sh
|
sh
Windows
PowerShell. From cmd: prefix with `powershell -c`.
PowerShell
ps1 · copy
1
irm
https://reactapistack.com/setup.ps1
|
iex
01 — Backend & storage
One TypeScript class becomes a REST API and an Iceberg-on-S3 table.
airports.ts
ts · copy
1
// airports.ts — one class → API + storage
2
import
{ MaxLength, Unique }
from
"rastack/db"
;
3
4
export
class
Airport
{
5
code
!:
string
&
Unique
&
MaxLength<3>
;
6
name
!:
string
;
7
}
02 — Frontend
Add rastack, wire the plugin, and pass your classes to the hooks — the schema compiles on save, fully typed, no generated files.
add rastack
ts · copy
1
# add to a project (typed hooks)
2
npm
install -D rastack
3
4
// vite.config.ts — schema compiles on save
5
plugins
: [
rastackPlugin
()]
6
7
// then anywhere in React — no codegen, no compile
8
import
{ useData }
from
"rastack/hooks"
9
const
airports
=
useData
(
Airport
)
Alpha — try it with npm
One class. The whole stack.
A clean React frontend and a backend that scales itself — with no servers to manage — all from a single TypeScript class.
A full-stack framework on object storage
Clean frontend, powerful backend, scale to millions.
React API Stack
© 2026 React API Stack — alpha
reactapistack.com