Written
A local-first journaling app focused on satisfying writing, privacy, and ownership.
Overview
Written is a journaling and writing app designed to make typing feel calm, private, and satisfying. The project evolved through several iterations—from early typing practice tools to a focused journaling experience—each version reflecting growth in frontend development, product thinking, and architecture. The app is built with a local-first mindset, prioritizing privacy, responsiveness, and offline use.
Media Gallery
Problem & Solution
Many journaling apps feel either overly complex or disconnected from the tactile satisfaction of writing by hand. Typing can feel sterile, and privacy is often unclear.
Written focuses on the writing experience itself: a minimal interface, local-first storage, optional encryption, and thoughtful customization. Features are added only when they improve daily use, guided by actively using the app as a journal.
Key Features
- Distraction-free journaling experience
- Local-first data storage using IndexedDB
- End-to-end encryption for journal entries
- Customizable cursor and text colors
- Optional on-device AI processing via local LLMs
- Cross-device sync with encrypted data
Technical Highlights
- Built with React and Vite using a component-driven design with shadcn/ui
- Implemented local-first storage using Dexie (IndexedDB)
- Added client-side encryption for journal entries to ensure data privacy
- Integrated WebLLM to run AI models locally without sending data to a server
- Built a custom sync engine from scratch, including encrypted push and pull logic
- Designed the system to function fully offline with optional sync
Challenges & Learnings
Local-First Sync with Encryption - Designed and implemented a custom sync system that supports encrypted journal entries, handling edge cases around conflict resolution, key management, and partial sync failures.
Client-Side Encryption - Implemented encryption for sensitive user data, balancing security, performance, and usability without relying on backend processing.
Running AI Locally - Integrated local LLMs using WebLLM, enabling users to analyze or reflect on their entries without uploading content to external services.
Product Focus & Restraint - Resisted feature creep by adding functionality only when it improved real usage, guided by daily use of the app as a journaling tool.
Product Decisions
- Actively used the app to guide feature development
- Prioritized privacy and ownership over convenience
- Chose local-first architecture to ensure reliability and trust
- Kept AI features optional, lightweight, and user-controlled
Interested in this project?
Check out the live demo or view the source code on GitHub