A self-hosted journaling app with local AI-powered theme extraction, weekly reflections, and handwriting OCR. Built with FastAPI + vanilla JS. All data stays on your machine.
- Markdown-based daily journal entries with auto-save
- AI-powered theme extraction (Ollama, llama3.1:8b)
- Handwriting OCR via camera/scan upload (Ollama, minicpm-v)
- Full-text search across all entries
- Weekly AI-generated reflections
- Entry statistics and theme tracking
- Multi-user support with cookie-based session auth
- File-based storage (no database needed)
- Export entries as markdown
- Fully self-hosted and private
- Python 3.8+
- Ollama — local AI inference engine
# Install Ollama (see https://ollama.ai) curl https://ollama.ai/install.sh | sh # Pull required models ollama pull llama3.1:8b # text (themes, reflections) ollama pull minicpm-v # vision (handwriting OCR) # Start Ollama (if not already running) ollama serve
-
Clone the repo:
git clone git@github.com:Singheskan/JournalAI.git cd JournalAI -
Create a virtual environment and install dependencies:
python3 -m venv venv source venv/bin/activate pip install -r requirements.txt
-
Ensure Ollama is running:
ollama serve
-
Start the server:
cd backend python main.py -
Open http://localhost:8000 in your browser.
- The app opens to today's date
- Start typing — entries auto-save after 2 seconds of inactivity
- AI automatically extracts 3-5 themes from your entry
- Today: click "Go to Today" in the sidebar
- Browse: click any date in "Recent Entries"
- Prev/Next: arrow buttons in the editor header
- Search: full-text search across all entries
- Click "Scan" in the header
- Pick a target date and upload a photo of handwritten text
- Preview the transcribed text
- Click "Add to Entry" to append it to the selected date's entry
Click "Weekly Reflection" — AI analyzes your last 7 days and generates reflection questions.
Click "Stats" for entry count, unique themes, and most common themes.
JournalAI/
├── backend/
│ ├── main.py # FastAPI app, all API endpoints
│ ├── ai_service.py # Ollama integration (themes, reflections, OCR)
│ ├── auth.py # Session-based authentication
│ ├── storage.py # File-based entry storage
│ ├── models.py # Pydantic models
│ ├── process_entries.py # Entry processing utilities
│ └── test_reflection.py # Reflection tests
├── frontend/
│ └── index.html # Single-page app (HTML + CSS + JS)
├── data/ # Created at runtime, gitignored
│ └── users/<name>/ # Per-user entries and metadata
├── requirements.txt
├── .gitignore
└── README.md
| Method | Endpoint | Description |
|---|---|---|
POST |
/api/register |
Register a new user |
POST |
/api/login |
Log in |
POST |
/api/logout |
Log out |
GET |
/api/entry/{date} |
Fetch entry for a date |
POST |
/api/entry/{date} |
Save entry (triggers theme extraction) |
GET |
/api/entries |
List all entry dates with themes |
GET |
/api/search?q={query} |
Full-text search |
GET |
/api/themes |
Unique themes with counts |
GET |
/api/reflection/weekly |
Generate weekly reflection |
GET |
/api/stats |
Entry statistics |
POST |
/api/ocr |
Transcribe handwritten text from image |
GET |
/api/export |
Export all entries as markdown |
- Check if Ollama is running:
ps aux | grep ollama - Start it:
ollama serve - Verify models:
ollama list - Test:
ollama run llama3.1:8b "Hello"
Change the port in backend/main.py:
uvicorn.run(app, host="0.0.0.0", port=8001)MIT