# Tablinum – Local-first database for the browser

> Source: <https://tablinum.dev/>
> Published: 2026-08-25 17:49:51+00:00

Encrypted sync. Built-in collaboration. Zero backend.

`$ npm install tablinum`

Every record is gift-wrapped with NIP-59 encryption. The relay stores and forwards encrypted blobs — it never sees your data.

A complete toolkit for local-first applications

Your app works offline. All data lives on your device in IndexedDB. No server required, no loading spinners.

Data syncs to Nostr relays, encrypted end-to-end with NIP-59 gift wrapping. Relay operators cannot read your data.

Share databases with invite links. Key rotation on member removal — like changing locks when a roommate moves out.

Define schemas with collection() and field.*() builders. Full TypeScript inference from schema to query results.

First-class reactive bindings using async runes. Queries inside $derived(await ...) auto-update when data changes.

Effect-based structured logging with timing spans. From full debug output to complete silence in one config line.

Use the Effect API for full control, or the Svelte API for reactive simplicity

``` js
import { Tablinum, collection, field } from "tablinum/svelte";

const schema = {
  todos: collection("todos", {
    title: field.string(),
    done: field.boolean(),
  }, { indices: ["done"] }),
};

export const db = new Tablinum({
  schema,
  relays: ["wss://relay.example.com"],
});

export const todos = db.collection("todos");
js
<script lang="ts">
  import { todos } from "$lib/db";

  let title = $state("");
  let pending = $derived(await todos.where("done").equals(false).get());

  async function addTodo() {
    await todos.add({ title, done: false });
    title = "";
  }
</script>

<form onsubmit={addTodo}>
  <input bind:value={title} placeholder="Add a todo..." />
  <button type="submit">Add</button>
</form>

{#each pending as todo (todo.id)}
  <div>{todo.title}</div>
{/each}
```

Data lives in IndexedDB on your device. Reads are instant, writes never block.

Every record is wrapped in NIP-59 gift wrapping. Relays see encrypted blobs, nothing more.

NIP-77 negentropy figures out what's missing and only transfers the difference.

Available everywhere

Your data arrives on every device and every collaborator, fully decrypted and ready to use.
