FrontierJS

Sierra

UI · Resource@frontierjs/sierra

Your file tree is the route table. A Resource is a service, made reactive.

$ npm i @frontierjs/sierra

Routing

File tree · dynamic · catch-all · layouts · groups

Routes come from the filesystem, so the URL structure and the folder structure cannot drift. Layouts nest by directory and groups organize without affecting the path.

src/routes/invoices/index.mesa   → /invoices
src/routes/invoices/[id].mesa    → /invoices/42
src/routes/[...404].mesa         → anything else
src/routes/_module.mesa          → the layout

Replaces

React Router configTanStack RouterNext app directory

Frontmatter

Title · guards · render mode, per route

Route metadata lives at the top of the route file rather than in a separate config, so moving a page moves its configuration with it.

Replaces

route config objectsroute manifest files

Resources

The API's four hook phases, client-side

A Resource binds a service to reactive state, with the identical around/before/after/error phases the server uses. Learn the pipeline once and it holds on both sides.

const invoices = createResource('invoices', {
  hooks: { around: { all: [withSpinner] } },
})
await invoices.find({ status: 'open' })

Replaces

TanStack Query + a storeSWR + ZustandRTK Query

make()

A blank record shaped by the schema's defaults

Start a create form from the schema itself, with declared defaults already applied and server-owned fields left out. No hand-written initial state to fall out of sync.

invoices.make()
// { total: 0, status: 'draft' }  — id and createdAt omitted

Replaces

hand-written initial form state

Schema

JSON Schema shipped into the bundle

The build puts your schema in the browser, so the client knows the same field rules the server enforces — without a second copy of them written in a client-side validator.

Replaces

duplicated Zod schemas on the client

Targets

spa · static · widget · extension

One route tree, several outputs, chosen at build time. A prerendered marketing page, an embedded widget and a browser extension come from the same components.

Replaces

separate build configs per output

Loading

Route loaders · parallel fetch · connection state

Data loading declared per route and resolved in parallel, with live connection state you can render against instead of tracking your own online flag.

Replaces

suspense boilerplatemanual loading flags

Devtools

Routes, resources, requests, events, jobs

An in-page overlay fed by the server's own telemetry, so you see the request, the hooks that ran and the job it queued in one timeline.

Replaces

React Query DevtoolsRouter Devtoolsnetwork tab archaeology

Build

Vite · state-preserving HMR · auto-imports

Vite underneath with Mesa compilation, hot replacement that keeps signal state across edits, and auto-imports so common components need no import line.

Replaces

hand-tuned Vite configplugin wiring