A fully client-side Markdown file viewer and editor. Browse your local folders, preview rendered Markdown in real time, edit files, and save changes — all inside the browser with no uploads, no server, and no dependencies to install.
🌐 Try it now: https://flavida.co/md-viewer
- Folder browser — Pick any local folder and navigate its contents like a file manager. Only Markdown files (
.md,.markdown) and sub-folders are shown, so the tree stays clean. - Real-time preview — Selecting a file instantly renders it as formatted HTML with syntax-highlighted code blocks. Files always open in rendered view by default.
- Mermaid diagrams — Fenced
```mermaidblocks render as live SVG diagrams (flowcharts, sequence diagrams, Gantt charts, and more) themed with the Flavida palette. - Full-text search — Press
Ctrl+F/⌘Fto search across every.mdfile in the selected folder. Results show the file name and a matching snippet. Select a result to open the file with all matches highlighted. - In-file match navigator — When a file is opened from search, a navigator bar shows the total match count and lets you step between every occurrence with
↑/↓buttons or keyboard shortcuts. The current match is highlighted in orange; all others in yellow. - Code / Rendered toggle — Switch between the rendered view and the raw Markdown source at any time. Edits in the source view are reflected immediately when you switch back to rendered.
- Create new file — Click the file
+button in the sidebar toolbar to create a new.mdfile in the current folder. The file is created instantly and enters rename mode so you can set a real name before writing. - Create new folder — Click the folder
+button in the sidebar toolbar to create a new sub-folder. It enters rename mode immediately so you can name it before using it. - Duplicate file — Click the duplicate icon in the preview toolbar (visible when a file is open) to copy the current file. The duplicate is named automatically (
title (2).md,title (3).md, etc.) and opened immediately. - Inline rename — Double-click any filename or folder name in the sidebar, or double-click the filename in the toolbar, to rename it in place. Press
Enteror click outside to save; pressEscto cancel. Works like macOS Finder / Windows Explorer. - Drag-and-drop move — Drag any file or folder onto another folder to move it there. A confirmation modal appears before the move executes. Drag to the toolbar area (folder name) to move an item to the parent directory.
- Delete file or folder — Click the trash icon that appears on hover next to any file or folder. A confirmation modal appears, followed by a 3-second undo window before the deletion is permanent. Folder deletion removes all contents recursively.
- Edit & save — The Save button appears only when unsaved changes are detected. Press
Ctrl+S/⌘Sor click Save to write back to disk. - Collapsible sidebar — Hide the file browser to focus on reading or writing. Toggle with the panel button or
Ctrl+B/⌘B. - Fullscreen preview — Expand the preview to fill the entire window with
F11. PressEscto exit. - Resizable panel — Drag the divider between the sidebar and the preview to adjust the split.
- Preferences remembered — Panel width and collapsed state are saved to
localStorageand restored on the next visit. - Privacy-first — Nothing leaves your machine. No analytics, no telemetry, no cloud storage.
Requires the File System Access API, available in:
| Browser | Minimum version |
|---|---|
| Chrome | 86+ |
| Edge | 86+ |
| Opera | 72+ |
| Safari | 15.2+ |
Firefox does not support this API as of mid-2025.
- Clone or download this repository.
- Open
index.htmlin Chrome or Edge. - Click Open a Folder and select a folder that contains
.mdfiles.
The browser will show a permission dialog before it reads your files. No data leaves your device.
If you need Safari compatibility or your browser restricts the File System Access API on file:// URLs, serve the folder over HTTP:
# Python (built-in, no install needed)
python3 -m http.server 8080 --directory /path/to/md-viewer
# Node.js (if you have npx available)
npx serve /path/to/md-viewerThen open http://localhost:8080 in your browser.
| Shortcut | Action |
|---|---|
Ctrl+S / ⌘S |
Save the current file |
Ctrl+Z / ⌘Z |
Undo file/folder deletion (during 3 s window) |
Ctrl+B / ⌘B |
Toggle the file browser sidebar |
Ctrl+F / ⌘F |
Focus the search bar |
Enter |
Next match (when match navigator is active) |
Shift+Enter |
Previous match (when match navigator is active) |
↓ / ↑ |
Next / previous match (when navigator is active and focus is outside editor) |
Esc |
Close modals / match navigator → clear search → exit fullscreen (in priority order) |
F11 |
Toggle fullscreen preview |
Double-click |
Rename any file or folder (sidebar or toolbar) |
md-viewer/
├── index.html — App shell and landing screen
├── style.css — All styles (Flavida design tokens + layout + Markdown typography)
├── app.js — All JavaScript (file system, navigation, preview, editor, UI state)
└── .claude/
└── launch.json — Dev server config for Claude Code preview
No build step, no package.json, no bundler. Everything runs directly in the browser.
All loaded from CDN — no local copies needed:
| Library | Version | CDN | Purpose |
|---|---|---|---|
| marked | 9.1.6 | cdnjs | Markdown → HTML parsing |
| DOMPurify | 3.0.8 | cdnjs | Sanitize rendered HTML |
| highlight.js | 11.9.0 | cdnjs | Syntax highlighting in code blocks |
| Mermaid | 10 | jsDelivr | Diagram rendering (flowcharts, sequence, Gantt, etc.) |
| Google Fonts | — | Bricolage Grotesque + DM Sans |
The app will work offline if your browser has cached these resources from a previous visit. For fully offline use, download the libraries and reference them locally in index.html.
When you click Open a Folder, the browser shows a native permission dialog for read and write access to the selected folder. This is handled entirely by the browser's File System Access API — no code on this page can access your files without that explicit grant.
Permissions are session-scoped. The next time you open the app, you'll be asked to pick a folder again. No file paths or handles are stored between sessions.
The sidebar works like macOS Finder or Windows Explorer in list view:
- Single-click a folder to navigate into it (with a short delay to allow double-click rename).
- Double-click any file or folder to rename it in place.
- Click the ↑ Up button or a breadcrumb segment to go back to a parent directory.
- Drag a file or folder onto another folder to move it. Drag to the toolbar area to move to the parent directory.
- Only
.md/.markdownfiles and folders are listed — other file types are hidden.
Clicking the trash icon next to a file or folder shows a confirmation modal. After confirming:
- The item disappears from the sidebar immediately.
- A toast notification with a 3-second countdown appears. Click Undo or press
Ctrl+Z/⌘Zto cancel. - If not undone, the item is permanently deleted from disk. Folders are deleted recursively (all contents removed).
The sidebar stays consistent across navigation — if you navigate away and back during the undo window, the pending-delete item remains hidden until the action resolves.
Press Ctrl+F / ⌘F to open the search bar in the left panel. As you type, the app reads every .md file in the selected folder (recursively) and returns matching files ranked by hit count. Each result card shows the file name and a text snippet around the first match.
Clicking a result opens the file and:
- Highlights every occurrence of the query with a yellow
<mark>. - Shows a match navigator bar below the preview toolbar with the total count and prev/next controls.
- Scrolls to and focuses the first match (orange highlight).
Use Enter / Shift+Enter or the ↑ / ↓ arrow keys to step through matches. The navigator bar closes when you clear the search or press Esc. Clearing the search returns the left panel to the directory where the opened file lives, and the preview scroll position is preserved.
The Save button only appears after you make a change in the Code view. When you save:
- The browser may prompt for write permission if it hasn't been granted yet this session.
- The file is written in place using
FileSystemFileHandle.createWritable(). - The rendered preview updates immediately to reflect the saved content.
The following preferences are stored locally and never sent anywhere:
| Key | Value |
|---|---|
mdviewer-prefs.panelWidth |
Sidebar width in pixels |
mdviewer-prefs.isPanelCollapsed |
true or false |
To reset preferences, run localStorage.removeItem('mdviewer-prefs') in the browser console.
Edit the --panel-w variable in style.css:
:root {
--panel-w: 280px; /* change this */
}All colours are Flavida design tokens defined at the top of style.css under :root. The primary accent colour is --color-flame: #E8391D.
In app.js, the file filter is in loadDirectory():
} else if (name.toLowerCase().endsWith('.md') || name.toLowerCase().endsWith('.markdown')) {Add more extensions here (e.g. || name.toLowerCase().endsWith('.txt')) to include them in the browser.
This is a static, dependency-free project — contributions should keep it that way. No build tools, no frameworks, no npm packages.
- Fork the repository.
- Make your changes to
index.html,style.css, orapp.js. - Test by opening
index.htmlin Chrome or running a local server. - Open a pull request with a clear description of what changed and why.
MIT — see LICENSE for details.



