Skip to content
chamixPublic

About

Markdown viewer desktop app

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

md-view

A minimal Electron + TypeScript desktop app for previewing Markdown files.

Features

  • Open files via native dialog or by passing a path as a CLI argument
  • Live-reload — watches the open file and re-renders automatically on save
  • GitHub-flavored rendering (GFM styling via github-markdown-css)
  • Syntax highlighting for fenced code blocks with a declared language (highlight.js)
  • Relative image paths in the Markdown source resolve correctly against the open file's directory
  • External links open in your system's default browser, not inside the app
  • Drag-and-drop a .md file from the OS onto the window to open it — same validation as File → Open, and only the first file is opened if several are dropped
  • Dark Mode and Show Frontmatter toggles in the View menu control preview appearance and frontmatter visibility
  • Persisted settings — View-menu toggles (Dark Mode, Show Frontmatter, Show File Tree) are saved to a settings.json in the app's per-user data directory and restored on the next launch. File → Settings opens (creating it first if needed) that file in your OS's default text editor for direct inspection/editing
  • In-app Help window with usage documentation, available via Help → md-view Help or the F1 key
  • Folder sidebar — File → Open Folder… (Ctrl/Cmd+Shift+O) opens a folder in a sidebar tree. Clicking a folder lazily expands it; clicking a file opens it in the main pane. The tree auto-expands to and highlights whichever file is currently open. A .. (up one level) row navigates to the parent folder. Drag the divider between the tree and the document to resize the sidebar. View → Show File Tree toggles the sidebar on or off. Dropping a folder onto the window also opens it as the tree root, the same as Open Folder…
  • Preview and Code tabs — View → Preview and View → Code switch the main pane between the rendered Markdown and a raw-source view with syntax highlighting. The raw view always includes frontmatter, regardless of the Show Frontmatter toggle, which only affects the rendered Preview
  • Copy raw source — a copy button in the document header copies the file's raw source, frontmatter included, to the clipboard regardless of which tab is active, with a brief visual confirmation on click
  • What's New on update — the first time you launch md-view after an update, a small window shows that version's release notes. Shown once per version, then not again until the next update
  • Close — File → Close (Ctrl/Cmd+W) closes the open file and returns to the "No file open" view. The folder tree stays open. The item is disabled when no file is open
  • Mermaid diagrams — fenced code blocks tagged mermaid render as diagrams in the Preview and follow Dark Mode. An invalid or oversized diagram shows a notice and its source without affecting the rest of the document. Theme and security settings inside a diagram are ignored. The Code tab and the copy button still show the raw Markdown
  • About window and third-party notices — Help → About md-view shows the app version, the Electron/Chromium/Node.js versions, copyright, license, a repository link, and the license notices of the open-source packages bundled into md-view (Electron's and Chromium's own license files ship alongside the app)
  • Copy text — select text in the Preview or Code view and copy it with Ctrl/Cmd+C or the right-click Copy menu item; right-click Copy All copies the whole visible view (the rendered document in Preview, including frontmatter when it's shown, or the raw Markdown source in Code). A Mermaid diagram always copies its Markdown source, never its rendered drawing, whether you right-click it directly, select across it, or include it in Copy All. There's no new top-level menu item for this — Copy and Copy All are context-menu and keyboard actions only
  • Skins — View → Skin picks the color scheme of the app chrome (title bar, tab strip, folder sidebar, status bar) and the code-highlighting colors. Four skins ship — Default, Claude, Obsidian, and Tokyo Night — each with independent light and dark halves; Dark Mode decides which half shows without ever changing which skin is active. View → Skin → Edit Skins… opens skins.json for hand-editing custom skins

Stack

  • Electron — desktop shell (main/preload/renderer process model)
  • TypeScript — compiles src/main and src/preload to CommonJS (dist/); the renderer is plain JS, no build step
  • markdown-it — Markdown → HTML conversion, with raw HTML passthrough explicitly disabled
  • highlight.js — syntax highlighting for fenced code blocks with an explicit, recognized language (no auto-detection). Eight of its theme stylesheets ship in dist/renderer/ — the default light/dark pair plus six more backing the Skins feature's code-highlighting halves
  • chokidar — file watching for live-reload
  • Mermaid (11.17.2, pinned) — diagram rendering in the Preview. Shipped as a build-time asset: npm run build copies mermaid.min.js into dist/renderer/, and the renderer loads it only when a document contains a diagram
  • zod — schema validation for the hand-editable settings.json file
  • esbuild — bundles the preload script into a single file (required to run under Electron's sandboxed preload context)
  • Vitest — unit and integration tests
  • Playwright (@playwright/test, _electron) — end-to-end tests against the built, packaged app
  • electron-builder — packages the compiled dist/ output into distributable binaries

Security invariants

  • contextIsolation: true, nodeIntegration: false, sandbox: true on the main window
  • The preload script exposes only an explicit, versioned bridge object (window.mdview) via contextBridge.exposeInMainWorld — never raw IPC or Node APIs
  • Markdown is converted with html: false — raw HTML embedded in a source file is never rendered as live markup
  • Links clicked inside rendered content are intercepted and opened externally via shell.openExternal; the app window itself never navigates away from its own content
  • The main window enforces a Content Security Policy (src/renderer/index.html): scripts load only from the app itself (no inline or eval'd scripts) and connect-src 'none' blocks script-initiated network requests (fetch/XHR/WebSocket). Remote images in a document still load. Mermaid runs with a locked configuration (securityLevel: 'strict', with theme and security keys that a diagram cannot override)
  • The Help, What's New, and About windows render under a no-script Content Security Policy: no script-src at all, and only the one embedded stylesheet, pinned by its SHA-256 hash

Usage

# Open a specific file directly
npm run dev -- path/to/file.md

# Or launch the app and use File → Open
npm run dev

File → Open Folder… (Ctrl/Cmd+Shift+O) is a second way to start: it opens a folder tree in the sidebar instead of a single file.

Commands

Command Description
npm run dev Build, then launch the app with electron .
npm run build Compile TypeScript, bundle the preload script, and copy static renderer assets into dist/
npm test Alias for test:all
npm run test:unit Run unit tests (tests/unit)
npm run test:integration Run integration tests (tests/integration)
npm run test:e2e Build, then run the Playwright end-to-end tests against the built app
npm run test:all Run unit, integration, and e2e tests in sequence
npm run test:coverage Generate a code coverage report for the unit test suite (tests/unit). Informational only — no enforced threshold
npm run package Package the built app with electron-builder

About this project

Status: v1.3.0. md-view is a small, working tool — and also a live testbed.

This app was built end-to-end under a governed, multi-agent development process: every feature went through explicit scope contracts, independent code review (including deliberate fault-injection to verify tests actually catch what they claim to), and a running decision log. The governance system itself lives in a separate, public repo — chamix/claude-blueprints — and is deployed into target repos like this one.

If you're curious about the process rather than just the app:

  • RUN_LOG.md — one row per completed task: cycles to green, reviewer verdict, notes
  • backlog.md — known follow-ups, tracked openly rather than fixed silently
  • .agents/specs/decisions/ — architecture decision records for the non-obvious calls
  • CHANGELOG.md — release history: what changed in each version

This is part of a broader learning project comparing agentic development workflows — this app is the first thing built under the current system, used partly to stress-test the governance itself.

License

MIT — see LICENSE.

The license notices of the open-source packages bundled into md-view ship with the app: npm run build generates them into dist/, and they are shown in-app under Help → About md-view.

About

Markdown viewer desktop app

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages