Journal App
A full-stack work journal that turns daily notes into a searchable personal knowledge base.
August 2025
- React
- FastAPI
- PostgreSQL
- SQLAlchemy
- Stripe
I built this app to serve as a centralized hub for journaling and note-taking β somewhere I can easily retrieve historical entries and use AI to summarize or surface deeper insights from my own data.
π‘ The Problem
I wanted a reliable, dedicated environment to log my thoughts, track my reading notes, and handle daily journaling. Existing tools lacked the specific flexibility I needed to turn raw text into an organized, easily searchable personal knowledge base. I wanted something entirely personal, contextual, and customizable.
π οΈ What I Built
Journal is a production-ready web app designed for low-friction daily logging.
- Streak tracker. A writing-streak indicator on the dashboard nudges users toward consistent, daily journaling.
- Organization and curation. Pin important entries, mark items as favorites, and catalog thoughts with custom notebooks and tags.
- Fast search. An optimized search lets users scan their historical text and retrieve information instantly.
- Subscription tier. A Stripe-backed paid tier β the free tier retains data for three months, and verified payment unlocks unlimited storage.
π» Technical Stack
- Frontend: React and TypeScript on Vite, deployed as a static SPA.
- Backend: FastAPI (Python) running in a lightweight container, with JWT-based authentication.
- Database & ORM: PostgreSQL managed via SQLAlchemy, with schemas designed for fast text querying and strict feature isolation.
- Payments: Stripe Checkout for subscriptions; webhooks update the userβs subscription state in the database.
π Whatβs Interesting
- Streak design. Visual streak indicators on the dashboard meaningfully improved daily interaction. Small UI affordances, big retention impact.
- Interconnected notes. Letting users explicitly link entries turns the app from a chronological diary into a web of connected knowledge β mirroring productivity philosophies like Zettelkasten.
- Data lifecycles. Writing background logic to expire free-tier data after three months, then cleanly extend it the moment a Stripe webhook fires, was a good lesson in state management and async event handling.