The Problem
Most browsers render HTML, which is fine for humans but noisy for anyone trying to read the web as structured text. AI tools strip pages down to markdown before processing them; there's no easy way to see that same clean view while browsing. md-browse closes that gap: a browser whose primary output is markdown, not rendered HTML.
What This Does
md-browse is a markdown-first desktop browser built on Electrobun (a Bun-based Electron alternative). It sends Accept: text/markdown headers when fetching pages and falls back to HTML-to-markdown conversion via Turndown when servers don't support native markdown. The UI lives in src/toolbar-svelte/ (Svelte + Vite), and the main process runs in src/bun/index.ts.
It supports multiple tabs with navigation history, back/forward, reload, and a toggle between raw markdown and rendered preview. The conversion pipeline in src/shared/turndown.ts is tuned to match what Copilot and Claude see: it strips scripts, styles, and navigation, extracts <main>/<article> content, and normalizes headings, links, and code blocks.
How It Is Wired
Execution starts in src/bun/index.ts. The entry points are fetchPage (line 197), sendNavigationState (line 346), and sendTabs (line 355). fetchPage reaches 6 functions and is called from 5 places; it fetches over HTTP, decodes the response body via decodeResponseBody, and runs content through the Turndown service from src/shared/turndown.ts. The Bun process owns all network I/O and state; it communicates with the Svelte toolbar over RPC (src/toolbar-svelte/lib/rpc.ts, 28 functions).
The highest-blast-radius functions are getElectroview (called from 12 places), sendNavigationState (10), and sendTabs (9) — all in src/bun/index.ts. Change any of these and a dozen call sites ripple. The module graph shows no circular dependencies (16 files, 15 edges), but src/shared/start-page.ts is a stable hub (5 importers, 0 dependencies) and src/bun/index.ts is an unstable sink (0 importers, 3 dependencies), so the main process is where most change concentrates.
How To Use It
# Install dependencies
bun install
# Run in development mode
bun run start
# Build the application (current platform)
bun run build
Requires Bun and macOS for native development. No environment variables or config files are needed beyond electrobun.config.ts. The README documents these commands verbatim; no other setup steps are evidenced in the repo.
Real-World Use
Documentation-heavy workflows: a developer reading Vercel's docs, which serve native markdown, gets the clean source immediately. For sites that only serve HTML, the Turndown pipeline in src/shared/turndown.ts produces a feed-ready markdown view — useful for content extraction, LLM prompt building, or archiving pages as text without scraping tools.
Code Health & Issues
Static analysis (deterministic, not opinion) found 5 issues across 4 kinds:
- High – duplicated code blocks: 73 repeated 6-line blocks across 6 files including
src/bun/index.ts,scripts/turndown.test.ts, andsrc/toolbar-svelte/lib/rpc.ts. Extract shared helpers. - Medium – high branching density:
src/shared/turndown.tshas 35 branch points over 73 lines; consider table/strategy dispatch. - Medium – oversized files ×2:
src/toolbar-svelte/App.svelteandsrc/bun/index.tsat 1,184 code lines; split by responsibility. - Medium – deep nesting:
src/bun/index.tsreaches indentation depth 6; flatten with guard clauses.
SDLC observations: no CI pipeline exists (15 source files, no workflow — every change merges unbuilt), no Dependabot/Renovate for the single manifest, and no .editorconfig/.gitattributes/formatter config. Tests are present (2 files) and a license exists; no committed secrets were found.
The Bottom Line
A focused, well-scoped tool that solves a real problem for markdown-centric browsing and AI-assisted reading. The architecture is clean — two processes, no circular deps — but src/bun/index.ts carries too much responsibility and the duplication across test and RPC files will slow future changes. Worth adopting if you work with LLM pipelines or documentation-heavy research; add CI before trusting it in a shared workflow.