Media Journal

A quiet, local-first place to write notes on the things you watch.

React 18 TypeScript Vite 6 Dexie IndexedDB vite-plugin-pwa Geist
View live →

The problem

A friend wanted to keep a small journal of what she watched — not Letterboxd, not a social feed, just notes for herself. Existing apps all want accounts, ratings out of five, a recommendation engine, friends. She wanted a quiet page that opened to a list of her entries and let her write a few sentences about the last thing she saw.

The approach

A local-first PWA. Everything lives in the browser via IndexedDB through Dexie — no backend, no accounts, no analytics, no tracking. Install to the home screen and it’s an app icon. Each entry is a free-form note attached to a title, with an optional rating, optional Wikipedia link search to fill in metadata, and a month-grouped timeline view. Theme follows the system or can be pinned to light or dark. The whole thing is small enough that there’s no router — useState and a couple of views are all it needs.

Media Journal — empty-state view with a single yellow card reading 'A quiet place — notes on the things you watch' and a + button in the corner

How it works

Vite + React 18 + TypeScript. Dexie wraps IndexedDB with a React-hooks integration so the UI reacts to changes without a global store. vite-plugin-pwa generates the service worker and manifest. Geist Variable is the only typeface. Export and import are JSON round-trips so a user owns their data — back it up to a Drive folder, restore on a new phone, no service to depend on. Deployed to Vercel as a static build with PWA cache headers tuned for offline use.

Results

  • Zero backend — IndexedDB only, no account, no sync, no tracking
  • PWA-installable — home-screen icon, offline-capable, runs full-screen
  • Wikipedia title search — quick metadata fill without a paid API
  • JSON export/import — user owns their data, no lock-in
  • Built for one person — a quiet tool for a friend, not a product