Typed client

The typed client

A schema-aware query builder with inferred row types, shipped as its own package.

npm install @minnowdb/client

@minnowdb/client is optional. SQL is Minnow's contract — the engine runs every statement on its own — and this package is one consumer of the primitives the engine publishes.

It ships separately for two reasons. It can move at its own pace without a version of the engine riding along; and building it only from published primitives is what proves those primitives are enough for anyone else to build a layer of their own. If the seam were incomplete, this package would be the first thing to break.

What you get

One schema declaration drives migrations, row types, and every query:

import { MinnowDatabase, column, schema, table } from "@minnowdb/core";
import { IndexedDbBlockStore } from "@minnowdb/core/storage";
import { createMinnow, type InferDatabase } from "@minnowdb/client";

const appSchema = schema([
  table("customers", {
    customer_id: column.number().unique(),
    name: column.string(),
    city: column.string().nullable(),
  }),
]);

interface DB extends InferDatabase<typeof appSchema> {}

const database = new MinnowDatabase(await IndexedDbBlockStore.open({ name: "shop" }));
await database.migrate(appSchema);
const db = createMinnow<DB>(database, { schema: appSchema });

const rows = await db
  .selectFrom("customers")
  .select(["name", "city"])
  .where("city", "=", "London")
  .execute();
// Array<{ name: string; city: string | null }>

The named interface DB extends InferDatabase<...> {} is the standard form: it keeps hovers, errors, and emitted declarations printing Minnow<DB> instead of the fully expanded schema, which matters as soon as you have more than a table or two.

Where to go next

  • Reading data — joins, expressions, aggregates, subqueries, and set operations.
  • Writing data — typed inserts, updates, deletes, and returning.
  • Live queries — subscribe to a query and get a fresh result after every relevant commit.
  • Schema & migrations — defining tables, constraints, and views. Part of @minnowdb/core, and usable without this package.
  • Extending Minnow — the primitives this package is built on, if you'd rather build your own layer.

It wraps either half of the worker pair

createMinnow takes a MinnowDatabase or a MinnowDatabaseClient, so moving the engine into a worker changes where you get the driver from and nothing about the queries you write. See Workers & multi-tab.

On this page