Your notes are the website.
The first note-taking app where the file format is the rendering target.
No Markdown source/preview split. No syntax to learn. No exporters. No lock-in.
Edit a note in our app. Open the same .html in any browser. Embed it anywhere.
Install · Features · Philosophy · vs Obsidian · Architecture · 中文
The screenshot above is the editor. So is the file on disk. So is what you see when you open it in any browser. One file. Zero conversion.
- 🎨 True WYSIWYG HTML editor — TipTap + ProseMirror. No "source vs preview" mode. What you type is the file.
- 📂 Local-first vault — folder of
.htmlfiles. Open them anywhere. Email them. Host them. Diff them in git. - 🔗 Wikilinks · backlinks · unlinked mentions · global graph (WebGL) — full PKM toolkit, ~90 Obsidian-equivalent features mapped 1:1.
- 🎬 Rich blocks Markdown can't reach — video (YouTube/Vimeo/Bilibili/HLS), audio (8 codecs), PDF, charts, API-call widgets, web cards, inline SVG, MathML, KaTeX, Mermaid.
- 🧠 AI gateway — bring your own key for OpenAI, Anthropic, OpenRouter, Ollama, LM Studio, DeepSeek, or any OpenAI-compatible endpoint. Chat with your vault, rewrite selections, summarize.
- 🔒 E2E encrypted sync — point at iCloud / Dropbox / Google Drive / WebDAV / Nextcloud. AES-256-GCM + PBKDF2 200k rounds. Your provider sees ciphertext.
- 🔌 Sandboxed plugins — Web Worker isolation, typed RPC, install from any GitHub URL. Plugins cannot read your disk or steal your localStorage; they call into a controlled API surface only.
- ⌨️ CLI for AI agents — ships an
obhbinary so Claude Code, Codex, or any shell script can drive your vault programmatically (16 commands,--jsonoutput). - 🌐 Web Clipper — Chrome MV3 extension powered by Defuddle (the same engine Obsidian's clipper uses).
- 📱 One codebase, every platform — Tauri 2 desktop (mac · win · linux) + iOS/Android (mobile builds).
# Option 1: download the .dmg from GitHub Releases (recommended)
open https://github.com/guanxiaol/obsidian-html/releases/latest
# Option 2: build from source
git clone https://github.com/guanxiaol/obsidian-html.git
cd obsidian-html
bash scripts/setup.sh # checks node/rust/xcode-clt, installs deps
pnpm tauri:dev # launch desktop appgit clone https://github.com/guanxiaol/obsidian-html.git
cd obsidian-html
bash scripts/setup.sh
pnpm tauri:build # produces .msi / .deb / .AppImagecd obsidian-html
cargo build --release --bin obh --manifest-path src-tauri/Cargo.toml
./src-tauri/target/release/obh --helpFull prerequisites & troubleshooting: QUICKSTART.md · environment doctor: pnpm doctor.
Every note app of the last fifteen years stores Markdown and renders it to HTML at display time. That transformation step is the silent tax on every PKM tool:
- It locks you into one renderer. Open your
.mdin any other tool and your callouts/wikilinks/embeds break. - It forces a duality — "source" vs "preview". Live Preview is a clever bandage; the duality never fully heals.
- It caps your expressiveness at whatever the renderer supports. Want a chart? An API widget? Inline SVG? A real iframe? You need a plugin. The plugin emits HTML strings into the Markdown. The Markdown stops being portable.
We propose the inverse: store the rendered form.
HTML files are documents. They open in browsers, render in emails, publish to the web, work in any embed context, and they support every visual primitive natively — video, interactive charts, inline SVG, custom elements, MathML — with zero conversion.
What you lose vs Markdown: nothing meaningful. We ship a WYSIWYG editor friendlier than Notion's. You never see angle brackets unless you want to.
What you gain: every file ships as a real website. Drag a note into a browser. Drop it into a Substack draft. Mail it. Host the folder on GitHub Pages — it is the public site.
"Markdown is a workaround for plain-text constraints that no longer exist. HTML doesn't have to be."
|
|
|
|
|
|
|
|
|
|
|
|
The starter vault (examples/vault-starter/) ships four polished case studies that exercise the full rendering pipeline — custom <style> blocks, inline SVG charts, Google Fonts, drag-and-drop JS, all rendered identically in the app and in any browser.
|
📨 CEO Quarterly Letter — A startup CEO's Q2 letter to the board: ARR numbers, 8-card KPI grid, hand-coded SVG charts (bar + donut + dual-line), OKR cards with progress bars, org chart, signed letter to "one year from now". Demonstrates production-grade business communication in a single |
🎯 Life Plan v2026 — A 33-year-old's full life map: net worth tracker, FI progress, life-wheel SVG radar chart, habit tracker table with inline progress bars, relationship map, books and decisions log, letter to future self. Demonstrates personal planning at depth. |
|
📌 Drag-Drop Corkboard — Free-form sticky notes + polaroids + handwritten fonts. Drag anywhere; positions persist via |
🤖 AI Agent Guide — A self-demonstrating bilingual onboarding doc for AI agents (Claude Code, Cursor, etc.) integrating with the vault. Explains the three view modes, working recipes, what AI can do via the source-mode + render workflow. |
Open the starter Daily/我的日历.calendar to see 8 example events spanning a month. Click empty slots to create events, drag to move them across days/times, switch between Month / Week / Day views, color-code by category.
| Obsidian-HTML | Obsidian | Notion | Logseq | Anytype | |
|---|---|---|---|---|---|
| File format | .html (the rendering target) |
.md (proprietary extensions) |
proprietary DB | .md |
proprietary DB |
| Open in browser | ✅ native | ❌ needs Publish | ❌ paid Publish | ❌ | ❌ |
| WYSIWYG, no preview mode | ✅ | ✅ | ❌ | ✅ | |
| Local-first | ✅ | ✅ | ❌ cloud | ✅ | ✅ (sync via relay) |
| Open source | ✅ MIT | ❌ closed | ❌ closed | ✅ AGPL | ✅ AGPL |
| E2E encrypted sync | ✅ built-in | 💲 paid add-on | ❌ | ❌ | ✅ |
| AI gateway (multi-provider) | ✅ 6 backends | 💲 plugin | ✅ Notion AI | ❌ plugins | ❌ |
| CLI for AI agents | ✅ obh |
❌ | ❌ API | ❌ | ❌ |
| Embeds (video/PDF/API/charts) | ✅ native HTML | ✅ | |||
| Plugin sandbox | ✅ Web Worker | ✅ | ✅ | ||
| Bundle size | 6.5 MB (.dmg) | ~100 MB | n/a (web) | ~150 MB | ~200 MB |
| Mobile | 🟡 Tauri 2 mobile | ✅ | ✅ | ✅ | ✅ |
| Founder lock-in risk | none (your files are HTML) | high (Markdown dialect) | very high | low | medium |
┌──────────────────────────────────────────────────────────────┐
│ Tauri 2 Desktop Shell │
│ (mac · win · linux · iOS · Android) │
├──────────────────────────────────────────────────────────────┤
│ Frontend: React 18 + TipTap 2 (ProseMirror) + Zustand │
│ ├─ 11 TipTap extensions (wikilink, callout, math, mermaid…) │
│ ├─ 8 interactive block types (video, API, chart, PDF, …) │
│ ├─ 13 panel components (file tree, graph, properties, AI…) │
│ ├─ AI gateway (Vercel AI SDK wrap, 6 providers) │
│ └─ Plugin host (Web Worker + typed RPC, 13 methods) │
├──────────────────────────────────────────────────────────────┤
│ Backend: Rust (Tokio + reqwest + aes-gcm + pbkdf2) │
│ ├─ vault_ops: atomic file r/w with traversal guards │
│ ├─ crypto: AES-256-GCM E2E layer │
│ ├─ sync: WebDAV PROPFIND/PUT + folder sync │
│ ├─ fetcher: HTTP proxy w/ SSRF + private-net blocking │
│ └─ obh CLI: 16 subcommands, --json output │
├──────────────────────────────────────────────────────────────┤
│ Storage: .html files + .obsidian-html/ config dir │
│ + IndexedDB drafts (crash recovery) │
│ + localStorage (settings, no secrets in v0.1) │
└──────────────────────────────────────────────────────────────┘
| Choice | Why not the alternative | |
|---|---|---|
| Desktop | Tauri 2 | Electron = 100MB and 500MB RAM. Tauri = 6.5MB DMG. |
| Editor | TipTap / ProseMirror | Lexical = worse table support. Slate = stability issues. contenteditable = no thanks. |
| State | Zustand | Redux = ceremony. Context = re-render hell on edit-heavy apps. |
| Crypto | AES-256-GCM + PBKDF2 200k | Argon2id better but aes-gcm crate is unimpeachable. Path is open for v2. |
| Plugin sandbox | Web Worker | iframe = leakier. WASM-only = limits API. Worker hits the sweet spot. |
| AI | Vercel AI SDK + openai-compatible |
Reinventing the wheel for 6 providers is silly when LangChain-equivalents exist. |
| Sync | WebDAV first, vendor protocols later | WebDAV is universally available; iCloud-direct requires platform crypto. |
| Source files | 138 |
| TypeScript LOC | 12,500 |
| Rust LOC | 2,800 |
| Frontend tests | 85 (Vitest) |
| Backend tests | 11 (Cargo, includes 8 security tests) |
| Bundle | 6.5 MB (.dmg) · 21 MB CLI |
| Features mapped from Obsidian | 90+ (~95% coverage) |
| AI providers supported out of the box | 6 (extensible) |
| Phases delivered | 5/5 (MVP → ecosystem) |
This project ships two foundational documents intended for adoption by other tools:
docs/SPEC.md— vendor-neutral spec for HTML-as-storage notes (semver, 14 sections, 5 conformance levels). Anyone can implement it; vaults stay portable across tools.docs/AGENT_API.md— the stable surface for AI agents (Claude Code, Codex, shell scripts) to read and write vaults: theobhCLI, an experimental JSON-RPC server, and reference snippets for Python / Node / Rust / shell to talk to files directly.
The bet: the format is the moat. If another note-app implements OBH, users can move between us without conversion. We'd see that as a win.
Your notes ARE the website — there's no separate "publish" target. A vault folder of .html files is already a working static site.
obh export-html ~/MyVault ./dist
# Now upload ./dist anywhere:
wrangler pages deploy ./dist # Cloudflare Pages
rsync -avz ./dist/ srv:/var/www/notes/ # Personal nginx / Caddy
netlify deploy --prod --dir=./dist # NetlifyThe full playbook — personal server (nginx + Caddy configs), Cloudflare Pages, Cloudflare Workers + R2, GitHub Pages, Vercel/Netlify, GitHub Actions auto-publish, custom domain + HTTPS, private notes, secondary development (forking, plugins, CLI scripting) — lives in docs/DEPLOYMENT.md.
- Phase 1 — MVP: vault, tabs, WYSIWYG editor, file tree, drag-drop attachments
- Phase 2 — Knowledge graph: wikilinks, backlinks, properties, search, command palette, Obsidian import
- Phase 3 — Rich content: WebGL graph, transclusion, math, mermaid, themes
- Phase 4 — Power features: Canvas (JSON Canvas), Bases (bidirectional), interactive blocks
- Phase 5 — Ecosystem: AI gateway, WebDAV/iCloud/E2E sync, sandboxed plugins, CLI, Web Clipper, mobile build config
- Phase 6 — Mobile builds shipped to App Store / Play Store
- Phase 7 — Real-time collaboration (Y.js / CRDT)
- Phase 8 — Plugin marketplace (curated GitHub registry)
- Phase 9 — Argon2id migration + OS-keychain credential storage
Open an issue if you'd like to push a future phase forward.
Yes, please! Read CONTRIBUTING.md — it covers:
- Dev setup in 60 seconds (
bash scripts/setup.sh) - How the codebase is organized
- Coding conventions
- PR checklist (tests must stay green, TS must compile, Cargo must check)
- Security disclosure policy (SECURITY.md)
First time? Look for issues labeled good-first-issue.
- 💡 Discussions — feature requests, Q&A, show & tell
- 🐛 Issues — bug reports
- 🔒 Security advisories — private vulnerability disclosure
- 📖 中文 README · Quickstart · Mobile guide · Project plan
The project gratefully builds on: Tauri, TipTap, ProseMirror, React, Defuddle, Vercel AI SDK, DOMPurify, KaTeX, Mermaid, Sigma.js.




