npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rastack

v0.0.69

Published

**A full-stack framework on top of object storage. Scale to millions.**

Readme

React API Stack

A full-stack framework on top of object storage. Scale to millions.

React API Stack is not a UI library and not "just" an API package — it is the whole vertical: the API exposure surface, the database storage layer, and the devops that ships them. You author one TypeScript resource and the framework derives everything from the React data hooks at the top to the Parquet files on S3 at the bottom, with a stateless Rust API in between.

            ┌─────────────────────────────────────────────┐
            │                React / Expo                  │   API EXPOSURE
            │   useData(Airport) / useForm(Flight)         │   SURFACE
            └───────────────────────▲─────────────────────┘
                                    │  your types, resolved via the manifest
            ┌───────────────────────┴─────────────────────┐
            │   TypeScript resources → compile step        │   API EXPOSURE
            │   FK inferred from types → manifest+OpenAPI  │   SURFACE
            └───────────────────────▲─────────────────────┘
                                    │  schema.rastack.json (manifest)
            ┌───────────────────────┴─────────────────────┐
            │        Rust API (rastack-server, axum)           │   API + ADMIN
            │  manifest-driven CRUD · FK validation ·      │
            │  Django-admin-style /admin DB browser        │
            └───────────────────────▲─────────────────────┘
                                    │  object_store
            ┌───────────────────────┴─────────────────────┐
            │     Apache Iceberg tables on S3 (Parquet)    │   DATABASE
            │   snapshots · ACID on object storage         │   STORAGE
            └───────────────────────▲─────────────────────┘
                                    │
            ┌───────────────────────┴─────────────────────┐
            │     AWS Lambda (stateless) + S3 (state)      │   DEVOPS
            │   compute/storage separation, IaC, scale-to- │
            │   zero — modelled on SurrealDB's Gen-3        │
            └─────────────────────────────────────────────┘

The three surfaces, one framework

| Surface | What it is | Package(s) | | --- | --- | --- | | API exposure | TypeScript resources → in-process compile (FK inferred from types) → manifest + OpenAPI → pass your type to useData / useForm (typed TanStack Query hooks, no codegen) | the repo root, published as rastack (npm) — components/, hooks/, theme/, … | | Database storage | A stateless Rust API that stores every model as an Apache Iceberg table on object storage — snapshots, ACID on S3, columnar Parquet | engine/ (serve/rastack-server) | | DevOps | Serverless Rust on AWS Lambda + S3: stateless compute, state in object storage, infrastructure-as-code, scale-to-zero — driven by rastack init / deploy / ci | deploy/cloudformation/, examples/serverless/ |

Install the CLI

One command, no clone — installs the rastack CLI into a per-user dir (~/.rastack, no sudo), the way you'd install Poetry or rustup. Node.js is the only prerequisite.

# macOS / Linux
curl -fsSL https://reactapistack.com/setup.sh | sh

# Windows (PowerShell) — from cmd, prefix with: powershell -c "…"
irm https://reactapistack.com/setup.ps1 | iex

Prefer a package manager, or adding it to a single project? npm install -g rastack (global CLI) or npm install -D rastack (project dependency) work too. Pin a version with RASTACK_VERSION=x.y.z before the installer.

Author once, compile the rest

// resources/airports.ts
import { resource, s } from "rastack/define";

export const Airport = resource("airports", "airport", {
  code: s.string({ maxLength: 3, unique: true }),
  name: s.string({ maxLength: 120 }),
});

export const Terminal = resource("airports", "terminal", {
  airport: s.ref(() => Airport),   // ← foreign key, detected from the type
  label: s.string({ maxLength: 20 }),
});
# No compile step to run — it happens in-process. Author your resources, then:
rastack dev                        # compiles, starts native rastack-server, proxies /api
rastack admin                      # Django-admin-style console served by that same binary
// Then just pass your type to the hooks — nothing is generated into your repo.
const airports = useData(Airport);
<DataTable query={airports} />

const form = useForm(Flight, { id });
form.transition("board");          // a typed, state-machine-safe save

The compile step runs a real TypeScript type checker and infers relationships straight from the field types — see docs/compile-and-relations.md; the hooks resolve your types against the compiled manifest at runtime — see docs/typed-hooks.md. Resources can declare state transitions (scheduled → boarding → departed), compiled into the manifest and enforced on every write by the native handler — an illegal jump is a 400 from the form, the importer, and rastack-server (laptop and Lambda).

Ship it — one command per stage

The DevOps surface is a CLI too. A new repo goes from nothing to deployed in three commands, and GitHub Actions stays a one-liner because the pipeline lives in the CLI, not the YAML:

rastack bootstrap                  # once per AWS account+region: buckets + GitHub OIDC
rastack init                       # per app: scaffold .github/workflows + .rastack/deploy.json AND stand the backend up
rastack ci deploy                  # what CI runs: build the arm64 Lambda, bake the JWKS, ship the code

bootstrap stands the tier-0 account stack up once (the template-hosting buckets + the GitHub OIDC provider), decoupled from any app. init is per-app: it scaffolds the base GitHub Actions and a deploy config (defaulting the GitHub coordinates from your origin remote), then stands the serverless backend up — deploying app.yaml, reading the stack Outputs back into the config, and wiring the GitHub repo Variables so the first push deploys. From then on infrastructure is fixed and CI only ships code: rastack ci deploy builds and runs update-function-code (rastack deploy is an alias for it), so a workflow step is just run: rastack ci deploy (rastack ci --plan deploy prints every step). Full guide: docs/serverless-deploy.md.

The UI is in the browser. The API is native Rust.

A browser cannot execute rastack-server. rastack dev starts that binary and proxies /api to it. The page renders your app. The request logic (rastack-api-core), the Iceberg warehouse, and access control run in the native process — the same binary Lambda runs (provided.al2023, cargo lambda build --arm64 --features lambda). There is no in-browser engine: no RastackApi, no warehouse seeded into the page, no IndexedDB copy of the database. The warehouse is the server's directory under data/warehouse.

// Local: this origin. rastack dev proxies /api to native rastack-server.
<RAStackProvider mode="local" manifest={schema}>
  <App />
</RAStackProvider>

// Production: the same hooks, over HTTP, to Lambda.
<RAStackProvider mode="remote" baseURL="https://api.example.com">…</RAStackProvider>

Full guide: docs/local-wasm-dev.md.

Why "on top of object storage"?

Traditional stacks pin you to a server-bound RDBMS. React API Stack instead puts S3 at the bottom of the stack as the system of record and runs the API as stateless, elastic compute on top — the same compute/storage-separation principle behind SurrealDB's Gen-3 architecture. That gives you:

  • Scale to millions — compute scales horizontally and independently of data; storage is S3's 11-nines durability and effectively unbounded capacity.
  • Scale to zero — when no requests are in flight, no compute runs and you pay only for object storage.
  • No vendor lock-in — data lives in open Apache Iceberg / Parquet, readable by Spark, DuckDB, Trino, and Polars.

Start here

Performance note. Apache Iceberg over S3 is currently the portable, correct-by-default storage path, not the fastest one. S3 first-byte latency dominates small OLTP reads. The roadmap closes this with a custom S3 backend fronted by a DynamoDB metadata/cache layer (and optionally EFS for hot IO) — see docs/architecture.md.