Public
Offline-first notes demo — IndexedDB via idb, synced to SQLite
httpsqlitestarter
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

📝 Offline-First Notes (idb demo)

A client-side demo of IndexedDB with usability — the idb library (by Jake Archibald). Notes are written straight to IndexedDB in the browser, so the app works offline, then a manual Sync pushes local changes to a server and pulls anything new back.

Try it: https://idb-demo.val.run/

What it demonstrates

idb featureWhere
openDB schema + upgrade migrationfrontend/db.ts
Typed DBSchema autocompletionfrontend/db.ts
Shortcut methods (db.put, db.get, db.getAll)frontend/db.ts
Indexes (getAllFromIndex)frontend/db.ts
Async iterators over a cursor index.iteratefrontend/db.ts
Transaction lifetime + tx.donefrontend/db.ts (sync)

The sync protocol is deliberately simple (teaching-grade, not production): each note carries updatedAt and a deleted tombstone, and merges use last-write-wins.

Architecture

Rendering mermaid diagram...

The same note record lives in IndexedDB (client, offline) and SQLite (server, shared) — nice symmetry for a demo.

Layout

index.ts              ← Hono backend: serves frontend + sync API (SQLite)
frontend/
  root.tsx            ← HTML shell (immutable asset URLs, Twind, std/catch)
  index.ts            ← client entry — vanilla DOM UI
  db.ts               ← idb wrapper: schema, CRUD, sync
  favicon.svg

How to demo it

  1. Open the app, add a few notes, then hit on one — all offline, nothing sent yet.
  2. Watch the status: "online / N unsynced changes".
  3. Click Sync → the badge drops to zero and a server round-trip happens.
  4. To see the offline story for real, open DevTools → Network → Offline, add more notes (badge shows offline, everything still works), go back online, Sync.
  5. Open the same app in a second tab/device and Sync — changes merge over since lastSyncAt.

API

  • GET /api/notes?since=<ms> — pull server notes newer than since.
  • POST /api/sync — atomically upsert a batch of local notes.

Env vars

None — the SQLite database is the val's built-in project-scoped database (std/sqlite/main.ts).