A personal knowledge base app, inspired by Obsidian. Notes are written in Markdown, linked to each other with [[double brackets]], and the links are visualized as an interactive graph.
This is a learning project. I built it to practice full-stack web development (Flask + PostgreSQL + vanilla JS) by cloning a real, feature-rich product from scratch. It started as a hackathon build and I kept extending it afterwards on my own to learn more. It won 1st place at my 3rd hackathon.
It is not a polished, maintained product β expect rough edges, and read the code with that in mind.
- Notes with Markdown β write, edit, pin, and search notes; split-view live preview.
- Wikilinks β type
[[Note Title]]to link notes; the note is auto-created if it doesn't exist yet. - Backlinks β see which notes link back to the one you're reading.
- Graph view β all notes and links rendered as an interactive force-directed graph (D3.js).
- Folders β organize notes into folders.
- Sharing β share a single note, a folder, or the whole graph via a public link.
- Public map β a shareable, read-only version of the graph view.
- Trash β soft-delete notes with restore/empty-trash.
- Image uploads β attach images and set a cover image per note.
- Export / import β back up notes as JSON and restore them.
- Auth β email/password login plus "Sign in with Google" (Authlib/OAuth).
- Notifications β in-app notifications, including admin-broadcast ones.
- Referral links β
/ref/<code>invite links. - Admin panel β manage users, view stats, moderate the blog.
- Blog β a small built-in blog/changelog.
- Help Center β multi-language (Uzbek, English, Russian) documentation pages, written directly in Python so docs ship in the same commit as the feature.
- Browser extension page β a landing page for a companion browser extension.
| Layer | Tech |
|---|---|
| Backend | Python 3, Flask, raw SQL via psycopg2 (PostgreSQL) |
| Frontend | HTML, CSS (custom, token-based), vanilla JS β no build step |
| Libraries (CDN) | Lucide (icons), Marked.js (Markdown render), D3.js (graph) |
| Auth | Flask sessions, Werkzeug password hashing, Google OAuth via Authlib |
| Deploy | Render.com (Gunicorn) |
There's no frontend build system (no webpack/npm) β the JS/CSS are loaded straight in the browser, which keeps the project simple and easy to deploy.
flint/
βββ app.py # Flask app: routes, auth, notes/folders/sharing API, admin API
βββ helpdocs/ # Help Center content (Python modules, one per topic)
βββ import_backup.py # Script to import a backup.json into the database
βββ requirements.txt
βββ Procfile # gunicorn start command
βββ render.yaml # Render.com blueprint (web service + Postgres)
βββ docker-compose.yml # Local Postgres for development
βββ templates/ # Jinja2 templates (app shell, login, admin, blog, help, public pages)
βββ static/
β βββ css/ # style.css (design tokens + theme), landing.css, help.css, mobile.css
β βββ js/ # app.js (notes/editor/wikilinks), graph.js (D3), help.js, i18n.js, sanitize.js
βββ instance/ # Local-only files (not committed)
You'll need Python 3 and a PostgreSQL database (the app no longer uses SQLite).
# 1. Start a local Postgres (optional, if you don't already have one)
docker compose up -d
# 2. Set up the Python environment
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
# 3. Set required environment variables
export DATABASE_URL="postgresql://flint:flint@localhost:5432/flint"
export SECRET_KEY="any-random-string-for-dev"
# Optional, only needed for "Sign in with Google" and email notifications:
# export GOOGLE_CLIENT_ID=...
# export GOOGLE_CLIENT_SECRET=...
# export SMTP_EMAIL=...
# export SMTP_PASSWORD=...
# 4. Run
python app.py # opens on http://localhost:5000The database tables are created automatically on first run.
The repo includes a render.yaml blueprint. Push to GitHub, then in the Render Dashboard choose New β Blueprint and pick the repo. Render will provision a free Postgres database and a web service, and ask you to fill in the Google OAuth / SMTP variables (optional).
I'm open-sourcing this mainly as a record of what I learned: Flask backend design, raw SQL with Postgres, session-based auth, OAuth, building a graph visualization from scratch, and a note-linking system. Feel free to look around, fork it, or use pieces of it in your own learning projects. Pull requests and issues are welcome, but I'm not actively maintaining this as a product.
This project is shared as-is for learning purposes. Feel free to use, modify, and learn from the code.