patrickz.aiLet’s talk ↗

Build apps / Project lab

Build a tracker that works without the network

Save, export and restore a small set of local records.

About 90 minutesSome experienceStack: TypeScript · IndexedDBUses a coding agentRead free · No sign-up

Open Perfect Zenkai (use “admin preview”) ↗See Patrick’s full project first, then build the tiny practice version below.

Before you start

A coding agent, browser and three fictional journal entries.

Why this lesson exists

The original offline-first personal tracker starts with one record type in IndexedDB and adds export before sync; accounts, cloud tables and conflict rules come later. This lab stops at an export and import you have tested.

Do the exercise

  1. Set your boundary

    Start with one record type, stable identifiers and local storage. Implement export before adding cloud synchronization.

  2. Choose one record type

    Choose one record type, such as a journal entry, with a stable ID and created and updated timestamps.

  3. Save it with IndexedDB

    Save and query it with IndexedDB.

  4. Add export and import

    Add a JSON export and an import that keeps the same IDs, before any sync.

Next sessions, not today

  • Module registry Add a module registry so features can be enabled independently.
  • Threat-model first Before adding accounts, threat-model where secrets could leak and how one user could reach another user’s records.
  • Accounts and cloud tables Add authentication and per-user cloud tables.
  • Sync conflicts Resolve sync conflicts with timestamps and visible status.

A prompt to adapt

Replace the bracketed parts with your own details.

Help me build an offline-first tracker in [TypeScript or JavaScript] in a new practice folder. First version only: one record type, [journal entries], with stable IDs and local storage, and export before any sync. No module registry, accounts, cloud tables or sync conflict rules yet, and no API secrets in client code. List the setup commands before changing any files. Then work in three checkpoints and, after each, tell me how to check it:
1. A data contract with a stable ID, created and updated timestamps and a deletion marker, shown as a TypeScript type.
2. Saving and querying records with IndexedDB, using the indexes you choose.
3. A JSON export and an import that keep the same IDs, plus a test that exports three entries, clears the store, imports them and compares every field.

More prompts to adapt ↗

Run this experiment

Create three entries, reload, export them, remove only the disposable test copy and import into a fresh practice profile. Compare fields and identifiers.

Check your result

Use evidence from your output. A confident explanation from the AI is not enough.

If it isn’t working

Do not add synchronization until conflict rules are explicit. Never embed production API secrets in client code.

Where this came from

Public project repository ↗. The practice lesson is an adaptation, not a verbatim transcript. About the sources.

Prepared September 2026. Tools and interfaces change; use current official setup instructions. Session lengths are estimates.

KEEP GOING

Your next useful step

Browse all 57 guides ↗