Skip to content
NewIntroducing Routier Devtools

RoutierReactive data for any datastore

A fast, front-end-first data toolkit with schemas, live queries, optimistic mutations, and swappable storage plugins. No lock-in, no rewrite.

npm install @routier/core @routier/datastore @routier/memory-plugin
Routier

Live demo

A live, paginated grid in one query

This grid is a real React or Vue component running on Routier in your browser. One useQuery call sorts, pages, and subscribes, so the page stays current with no cache to invalidate and no refetch to wire up. Try restocking a row, turning on traffic, or switching frameworks: both read the same store. Then open the Routier button in the bottom-right corner: devtools shows this store's rows and every query the grid runs.
ProductGrid.tsxthe code this grid runs
import { useState } from "react";import { useQuery } from "@routier/react";import { store, type Product } from "./inventory";export function ProductGrid() {  const [page, setPage] = useState(1);  const [pageSize, setPageSize] = useState(6);  const rows = useQuery<Product[]>(    onResult =>      store.products        .sort(p => p.name)        .skip((page - 1) * pageSize)        .take(pageSize)        .subscribe()        .toArray(onResult),    [page, pageSize],  );

New · Devtools

See inside your store

@routier/devtools adds a drawer to your page that shows what your store holds and how every query runs. One line to set up, in React, Vue, or plain JavaScript, and stripped from production builds. It is running on this page now: click the Routier button in the bottom-right corner.
mountRoutierDevtools(store);
  • The Routier devtools Data view: a collection list with row counts, a table of products, and one product's full value.

    Your data, live

    Every collection and view with a live row count, a paged table of rows, and the full value of any row. It updates as saves, syncs, and other tabs change the data.

  • The Routier devtools Queries tab: a recorded query on SQLite, with the SQL statement and bound parameters it sent.

    Every query, explained

    The Queries tab records each query your app runs and shows its plan: the SQL or other statement it sent, its parameters, and anything that ran in memory, and why.

What you get

Everything a data layer needs, built in

Start with a schema and a plugin. Reach for the rest when your app needs it.

Swappable storage

Change one line. Keep your app.

The grid above runs on the memory plugin. Moving it to IndexedDB, SQLite, or PostgreSQL means changing the plugin the store is built with, and nothing else.
import { MemoryPlugin } from "@routier/memory-plugin";class InventoryStore extends DataStore {  products = this.collection(productSchema).proxy().create();  constructor() {    super(new MemoryPlugin("inventory"));  }}
npm install @routier/memory-pluginRuns in: AnywhereMemory plugin docs →

Why Routier

The data layer you would end up building anyway

Every app grows a data abstraction: defaults, business rules, computed fields, and adapters for whatever datastore you started with. That works until you hit a performance ceiling, need local-first, or want different storage. Routier is that layer, datastore-agnostic and under your control.
  • Enhance, don't replace

    Keep your existing datastore. Add structure with schemas and defaults, speed with indexes and caching, and better ergonomics with live queries and optimistic updates.

  • Swap without rewrites

    Move from IndexedDB to SQLite or adopt OPFS by changing the plugin. Your app code remains unchanged.

  • Type checking by choice

    Use Zod or AJV for validation. Routier handles transformation and persistence.

  • Client-first, backend-capable

    Designed for the browser and local-first workflows, while remaining adaptable to backend runtimes.

Released under the MIT License.