Markdown Reader is a desktop Markdown editor and reader built with a Next.js frontend, a local FastAPI backend, AI-assisted editing tools, and native desktop packaging through Tauri.
Get the app running in under a minute:
# Prerequisites: Python 3.11+, Node.js 18+, and uv
git clone https://github.com/petertzy/markdown-reader.git
cd markdown-reader
# Install dependencies
uv sync
cd frontend && npm install && cd ..
# Configure frontend
cp frontend/.env.local.example frontend/.env.local
# Launch in development mode (opens a Tauri desktop window)
./scripts/dev-tauri.shOpen http://127.0.0.1:8000/docs for the backend API docs. Press Ctrl+C to stop.
For contributors: After cloning, also run
uv sync --extra devanduv run pre-commit installto set up linting hooks.
- Edit Markdown with a split editor and live preview experience.
- Open and work with Markdown files from a native desktop app window.
- Import content from Markdown, HTML, and PDF.
- Use AI-assisted translation, summarization, table-of-contents generation, formatting, and code-block cleanup.
- Configure OpenAI Compatible, OpenRouter, OpenAI, and Anthropic providers from the app.
- Review AI suggestions before applying them, with support for rejection, rollback, and audit tracking.
- Export rendered documents through the local backend.
- Build a single packaged desktop app with the Python backend bundled as a Tauri sidecar.
Markdown Reader is split into three main layers:
MarkdownReader/
├── backend/ # FastAPI app, routers, rendering, export, and AI APIs
├── frontend/ # Next.js UI and Tauri desktop shell
├── markdown_reader/ # Legacy Tkinter app logic (preserved for reference)
├── scripts/ # Development and release helper scripts
├── tests/ # Python tests for backend and AI workflow logic
├── docs/ # Additional project and platform notes
├── README_REFACTORING.md # Archived refactoring/migration notes
└── README_OLD.MD # Legacy Tkinter-era documentation
- Launches a real Tauri desktop window instead of a browser tab.
- Frontend 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.
- Users launch one app only:
Markdown Reader.app. - Python backend is bundled as a Tauri sidecar process.
- Backend port is dynamically assigned by the OS at runtime (no hard-coded ports in desktop mode).
After the desktop window opens, use Markdown Reader to:
- Open Markdown files for editing and live preview.
- Work with multiple document tabs.
- Import supported document formats (Markdown, HTML, PDF).
- Use AI tools from the AI panel to translate, summarize, format, or prepare document edits. Review suggested changes before applying them.
- Configure AI providers, models, base URLs, and API keys from the app settings (keys are saved via the system credential store).
The FastAPI backend exposes these route 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
Most contributors should use ./scripts/dev-tauri.sh, but you can start
services individually for debugging:
# Backend
uv run uvicorn backend.main:app --host 127.0.0.1 --port 8000 --reload
# Frontend (in a separate terminal)
cd frontend && npm run dev
# Tauri shell (with frontend dev server already running)
cd frontend && npm run tauri:devBuild the Python backend sidecar:
uv run pyinstaller markdown-reader-backend.specCopy the sidecar binary into the Tauri binary directory. For 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 platforms, use the matching Rust target triple as the sidecar filename suffix.
Build the desktop bundle:
cd frontend && npx tauri build --bundles appOutput (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. If a local beta build is blocked after download, run:
xattr -dr com.apple.quarantine "/Applications/Markdown Reader.app"For release packaging, use:
./scripts/package-macos-release.shAI features can be configured from the app toolbar through the Settings tab in the AI panel.
Supported providers:
- OpenAI Compatible
- OpenRouter
- OpenAI
- Anthropic
Provider and model preferences are saved per-user in the local app settings file. API keys are saved through the system credential store when available.
uv sync --extra dev # install dev dependencies
uv run pre-commit install # install git hooksuv run ruff check . # lint
uv run ruff format --check . # check formatting
uv run ruff format . # auto-formatuv run python -m unittest discover -s tests
uv run python -m unittest tests/test_ai_automation_logic.py # single filecd frontend && npm run buildPython dependencies are managed through pyproject.toml and uv.lock.
Use uv sync for normal setup. If dependencies change, regenerate and commit
the lockfile:
uv lock
git add pyproject.toml uv.lock && git commit -m "chore: update dependencies"CI runs uv sync --locked, so uv.lock must stay in sync with
pyproject.toml.
Frontend dependencies are managed with npm and frontend/package-lock.json.
Additional notes live in docs/:
Contributions are welcome. Typical workflow:
git checkout -b your-branch-name
uv sync --extra dev
cd frontend && npm install && cd ..
uv run pre-commit installBefore opening a pull request, run the relevant checks:
uv run ruff check .
uv run ruff format --check .
uv run python -m unittest discover -s tests
cd frontend && npm run buildKeep changes focused, update documentation when behavior changes, and include tests for backend or workflow changes where practical.
For more details, see CONTRIBUTING.md.
See LICENSE.
