jotaBase

An offline-first backend, built on the edge.

A sync engine that treats the network as optional — your app reads and writes locally, and reconciles when it can.

What it does

Quick start

  1. Set yourself up in the dashboard

    Everything here is a one-time setup, and the last step gives you the key the code below needs.

    • Register at app.jotabase.com, and confirm your address if you’re asked to.
    • Create a database — a lowercase name, like notes.
    • Open it, go to the API Keys tab, and click + Publishable key.
    • Copy the key now. It’s shown once and never again.
  2. Install the client

    npm install @jotabase/client
  3. Connect

    Keep the key you just copied in an env file rather than in source, so rotating it is a one-line change. Publishable keys are safe to ship in a frontend bundle — a secret key never is, and belongs on a server only.

    # .env.example — commit this, copy it to .env, fill in your key there
    VITE_JOTABASE_URL=https://api.jotabase.com
    VITE_JOTABASE_PUBLISHABLE_KEY=pk_live_...
    import { createClient } from "@jotabase/client";
    
    const jb = createClient({
      url: import.meta.env.VITE_JOTABASE_URL,
      publishableKey: import.meta.env.VITE_JOTABASE_PUBLISHABLE_KEY,
    });

    The VITE_ prefix is what exposes a variable to browser code under Vite. Other bundlers use their own — NEXT_PUBLIC_ for Next.js, PUBLIC_ for Astro and SvelteKit.

  4. Open the database

    Use the name you gave it. Naming one you never created is fine too — the first write brings it into existence.

    const db = jb.db("notes");
    await db.open();          // loads the saved checkpoint
  5. Write and sync

    Writes land locally first and are pushed in the background, so they survive a dropped connection.

    await db.put({ id: "note-1", data: { title: "Hello", done: false } });
    
    // Pull everything since the last checkpoint.
    await db.sync();
    const note = await db.get("note-1");
    
    // Re-sync automatically whenever the server changes.
    db.subscribe(() => render());
  6. Sign your users in (optional)

    Everything above works with the key alone. Add end-user auth when your users need roles, or rows only they can see.

    const auth = jb.auth("notes");
    const { token } = await auth.signIn({ email, password });
    jb.setToken(token);       // syncs now run as this user, with their roles

Status

jotaBase is in active development and not yet generally available. The dashboard is live for existing accounts.