Modern Markdown editor with a Next.js UI, FastAPI backend, AI features, and desktop packaging via Tauri.
Planning notes: scripts/ProjectPlan.md
- Launches a real Tauri desktop window instead of a browser tab
- Frontend still runs from the Next.js dev server on
http://localhost:3000 - Backend runs from the FastAPI dev server on
http://127.0.0.1:8000 - Recommended start command:
./scripts/dev-tauri.sh - In this mode, the Tauri shell talks to the fixed dev backend on port
8000 - The packaged Python sidecar is not used in debug mode
- Users launch one app only:
Markdown Reader.app - Python backend is bundled as a sidecar process
- Backend port is dynamically assigned by the OS at runtime (no hard-coded 8000/3000 in desktop mode)
- Frontend discovers backend port through a Tauri command
This avoids port collisions with local services and allows multiple app instances more safely.
MarkdownReader/
├── backend/ # FastAPI app and routers
├── frontend/ # Next.js + Tauri desktop shell
├── markdown_reader/ # Existing Python business logic (preserved)
├── scripts/dev-tauri.sh # Recommended native dev startup
├── tests/ # Unit/integration tests
├── README_OLD.MD # Legacy tkinter-era documentation
└── pyproject.toml
- Python 3.11+
- uv
- Node.js 18+
uv sync
cd frontend && npm installNote for contributors:
pre-commitis required for git hooks (code linting/formatting runs on every commit). If you seeNo module named pre_commitwhen committing, run:uv add --dev pre-commit uv run pre-commit install
cp frontend/.env.local.example frontend/.env.local./scripts/dev-tauri.shOpen:
- Backend docs: http://127.0.0.1:8000/docs
- Tauri native app window: launched automatically by
./scripts/dev-tauri.sh
Press Ctrl+C in the terminal running ./scripts/dev-tauri.sh.
The desktop build produces one user-facing app and bundles the backend internally.
Follow OS prerequisites:
Install frontend tooling:
cd frontend
npm install
npm install -D @tauri-apps/cli @tauri-apps/apicd ..
uv run pyinstaller markdown-reader-backend.specFor Apple Silicon macOS:
cp dist/markdown-reader-backend frontend/src-tauri/binaries/markdown-reader-backend-aarch64-apple-darwin
chmod +x frontend/src-tauri/binaries/markdown-reader-backend-aarch64-apple-darwinFor other targets, use the corresponding Rust target-triple suffix.
cd frontend
npx tauri build --bundles appOutput path (macOS):
frontend/src-tauri/target/release/bundle/macos/Markdown Reader.app
Public macOS downloads need Developer ID signing and Apple notarization to open without Gatekeeper warnings. The current beta build is signed but not notarized. If macOS blocks the downloaded app, move it to Applications and run:
xattr -dr com.apple.quarantine "/Applications/Markdown Reader.app"
open "/Applications/Markdown Reader.app"For public releases, use scripts/package-macos-release.sh with a Developer ID
Application certificate and notarization credentials.
Main groups:
/api/files/*/api/markdown/*/api/ai/*/api/export/*
Health endpoint:
GET /api/health
Interactive docs (dev mode):
- Swagger:
http://127.0.0.1:8000/docs - ReDoc:
http://127.0.0.1:8000/redoc
AI features can be configured from the app toolbar through the Settings tab in the AI panel.
Supported providers:
- OpenAI Compatible
- OpenRouter
- OpenAI
- Anthropic
The settings UI lets users choose the active provider, select a model, fetch available models, save or delete API keys, and choose an OpenAI Compatible base URL preset when applicable. Provider and model choices are saved in the per-user settings file, while API keys are saved through the system credential store when available.
- In development mode, fixed ports (
3000and8000) are used for convenience. - In packaged desktop mode, backend uses a dynamically assigned local port.
- This is intentional and follows common desktop-app sidecar practices.
The old tkinter entrypoint is preserved:
uv run python app.pyLegacy docs: README_OLD.MD