Most Markdown editors on Linux break some part of real-world documents. Code blocks get mangled, tables render wrong, or the app hangs on a big file. IDE previews render well, but that's a lot of IDE to open for editing one README.
mdedit is a single ~7.5 MB binary that opens instantly. Its preview renders like GitHub: GFM tables, highlighted code in every language, math, and Mermaid diagrams.
Complex documents are where mdedit shines. Code blocks nested inside lists and quotes, tables mixing inline code and math, diagrams, alerts and footnotes all render correctly, even when they're combined in the same file. Text full of dollar amounts stays intact too, where other editors turn it into math.
- GitHub-style rendering: tables, task lists, footnotes, alerts, emoji, math, and Mermaid diagrams.
- Syntax highlighting for fenced code in all languages, in both the editor and the preview.
- Live preview that only redraws what changed, so images and diagrams don't flicker as you type.
- Three view modes (Source, Split, Preview) with synchronized scrolling.
- Tabs and a sidebar listing the Markdown files in the current folder.
- One-click HTML export to a single self-contained file.
- Font settings: typeface and size for the editor and the preview.
- Safe file handling: atomic saves, reload on external changes, and a prompt before discarding unsaved work.
- Light and dark themes that follow your system.
The preview updates as you type. Only the blocks you change are redrawn, so the view stays still, and images and diagrams don't reload or flicker.
Switch with the toolbar or Ctrl+1 / 2 / 3. You can drag the splitter in Split mode, and the position is remembered.
The editor and preview stay aligned by source line, even across tall diagrams and code blocks. Whichever pane you scroll leads the other.
The sidebar lists the Markdown files next to the current file and updates when
files are added or removed. Click one to open it in a tab. Running mdedit other.md
while the app is open adds a tab to the existing window.
| Diagrams | Code | Math, alerts, task lists |
|---|---|---|
![]() |
![]() |
![]() |
Everything that's supported
| Feature | Syntax |
|---|---|
| CommonMark + GFM | headings, lists, emphasis, links, images, autolinks, ~~strike~~ |
| Tables | pipe tables with :--, :-:, --: alignment |
| Task lists | - [ ] / - [x] |
| Fenced code | ```lang highlighted by highlight.js (190+ languages), with a copy button |
| Math (KaTeX) | $inline$, $$block$$, ```math |
| Diagrams (Mermaid) | ```mermaid for flowcharts, sequence, class, state, gantt, … |
| Alerts | > [!NOTE], [!TIP], [!IMPORTANT], [!WARNING], [!CAUTION] |
| Footnotes | text[^1] … [^1]: note |
| Definition lists | Term / : Definition |
| Extras | ==mark==, H~2~O, x^2^, :emoji: |
| Front matter | YAML --- block, shown dimmed at the top |
| Raw HTML | <details>, <kbd>, <img>, … (scripts and event handlers are stripped) |
| Heading anchors | GitHub-style ids, so [link](#some-heading) works |
Clicking a link works like this:
#anchorscrolls the preview.- A relative
.mdlink opens in a new tab. - A web link opens in your browser.
Relative image paths load from the file's folder.
Math support usually costs you your prices. Many editors, IntelliJ's Markdown preview
among them, pair up any two $ signs, so $4,743.00M and ... $2,127.00M becomes a
run of italic math. mdedit follows Pandoc's rules:
- an opening
$must be followed by a non-space - a closing
$must follow a non-space and can't be followed by a digit
So financial reports keep their numbers, and $x^2$ is still math.
Click Export HTML (or press Ctrl+E) to write name.html next to
your file. The export is a single standalone page:
- all styles are inlined
- diagrams are embedded as SVG
- local images are embedded, so nothing breaks when you share the file
- light and dark themes follow the reader's system
The one exception is KaTeX's fonts, which load from a CDN.
The Aa button sets the typeface and size for the editor (monospace fonts only) and for the preview. Code blocks in the preview use the editor font. Ctrl+= / - zooms both.
Get the latest build from the Releases page:
| Platform | File |
|---|---|
| Windows 10/11 | mdedit_*_x64-setup.exe (installer), or mdedit_*_x64-portable.exe (no install) |
| macOS (Intel and Apple Silicon) | mdedit_*_universal.dmg |
| Debian / Ubuntu | mdedit_*_amd64.deb, installed with sudo apt install ./mdedit_*.deb |
| Fedora / openSUSE | mdedit-*.x86_64.rpm |
| Any Linux distro | mdedit_*_amd64.AppImage (chmod +x, then run it) |
| Linux, plain binary | mdedit-*-linux-x86_64.tar.gz (needs WebKitGTK 4.1 installed) |
Arch Linux: build a native package with the PKGBUILD in
packaging/aur. An AUR package is coming soon.
git clone https://github.com/timofey/mdedit.git && cd mdedit/packaging/aur && makepkg -siWindows: the installer isn't code-signed, so SmartScreen may show "Windows protected your PC". Click More info, then Run anyway.
macOS: the app isn't signed with an Apple Developer ID, so macOS blocks the first launch. After dragging mdedit to Applications, run:
xattr -dr com.apple.quarantine /Applications/mdedit.appYou can also right-click the app, choose Open, and confirm.
Building from source takes a couple of minutes.
You need Rust (stable) and Node.js 20+, plus some platform tools:
Arch Linux
sudo pacman -S --needed base-devel webkit2gtk-4.1 rust nodejs npmDebian / Ubuntu
sudo apt install build-essential curl file libwebkit2gtk-4.1-dev libssl-dev \
libayatana-appindicator3-dev librsvg2-dev nodejs npmFedora
sudo dnf install webkit2gtk4.1-devel openssl-devel curl file \
libappindicator-gtk3-devel librsvg2-devel nodejs npm
sudo dnf group install c-developmentmacOS
xcode-select --install # Command Line Tools
brew install node rustup && rustup-initWindows
In PowerShell:
winget install --id Microsoft.VisualStudio.2022.BuildTools --override "--wait --passive --add Microsoft.VisualStudio.Workload.VCTools --includeRecommended"
winget install --id Rustlang.Rustup
winget install --id OpenJS.NodeJS.LTS
winget install --id Git.GitReopen the terminal afterwards so the tools are on PATH.
- WebView2: it ships with Windows 11 and current Windows 10. If it's missing, run
winget install Microsoft.EdgeWebView2Runtime. - Script policy: if
npmfails with "running scripts is disabled", runSet-ExecutionPolicy -Scope CurrentUser RemoteSigned, or usecmd.exe.
git clone https://github.com/timofey/mdedit.git
cd mdedit
./scripts/install-local.shThis builds a release binary and installs it for your user:
- the binary at
~/.local/bin/mdedit - a desktop entry, so mdedit shows up in your launcher and in Open with for
.mdfiles - the app icon
No root is needed.
To make mdedit the default app for Markdown files:
MDEDIT_SET_DEFAULT=1 ./scripts/install-desktop.shgit clone https://github.com/timofey/mdedit.git
cd mdedit
npm install
npx tauri build --bundles appThis builds src-tauri/target/release/bundle/macos/mdedit.app. Drag it to /Applications.
To use it from the terminal, symlink the binary inside the bundle:
ln -s /Applications/mdedit.app/Contents/MacOS/mdedit /usr/local/bin/mdeditgit clone https://github.com/timofey/mdedit.git
cd mdedit
npm ci
npx tauri build --bundles nsisThis builds an installer at src-tauri\target\release\bundle\nsis\mdedit_*_x64-setup.exe.
The plain executable src-tauri\target\release\mdedit.exe also runs without installing.
- Debian package:
npm install && npx tauri buildwrites a.debtosrc-tauri/target/release/bundle/deb/. - Desktop entry only:
./scripts/install-desktop.sh [path/to/mdedit]regenerates just the.desktopfile and icons, for example after moving the binary.
mdedit # restore the tabs from last time
mdedit README.md notes.md # open files (a running instance gets new tabs)
mdedit new-file.md # open a file that doesn't exist yet; it's created on saveYou can also drag files onto the window.
On macOS, use ⌘ in place of Ctrl. Tab switching stays on Ctrl+Tab, because ⌘+Tab belongs to the system.
| Keys | Action |
|---|---|
| Ctrl+N / Ctrl+O | New / Open |
| Ctrl+S / Ctrl+Shift+S | Save / Save As |
| Ctrl+W | Close tab |
| Ctrl+Tab / Ctrl+Shift+Tab | Next / previous tab (also Ctrl+PgDn / PgUp) |
| Ctrl+1 / 2 / 3 | Source / Split / Preview |
| Ctrl+B | Toggle sidebar |
| Ctrl+E | Export HTML |
| Ctrl+F | Find / replace |
| Ctrl+= / Ctrl+- / Ctrl+0 | Zoom in / out / reset (also Ctrl+scroll) |
- Line endings and permissions are preserved. Saves write to a temporary file first, so a crash can't leave a half-written file.
- External changes: if a file changes on disk and you have no unsaved edits, it reloads silently. If you do have edits, a bar offers Reload or Keep my version.
- Preferences: view mode, split position, sidebar, zoom, fonts, and open tabs are remembered between launches.
- NVIDIA (Linux): WebKitGTK often draws blank or flickering windows on NVIDIA GPUs.
mdedit sets
WEBKIT_DISABLE_DMABUF_RENDERER=1by default to avoid this. Set the variable yourself to override it.
| Layer | Choice |
|---|---|
| App shell | Tauri 2 (Rust) using the system webview (WebKitGTK on Linux, WKWebView on macOS, WebView2 on Windows), with no bundled browser |
| Editor | CodeMirror 6 with Markdown and nested code-language highlighting |
| Markdown | markdown-it and plugins |
| Code highlighting | highlight.js |
| Math / diagrams | KaTeX / Mermaid (loaded only when a diagram appears) |
| Styling | github-markdown-css |
| Sanitizing | DOMPurify |
The UI is plain TypeScript with no framework. The Rust side is under 200 lines and handles file I/O, the folder watcher, the font list, and single-instance handling.
npm install
npm run tauri dev -- -- path/to/file.md # run with hot reload
npm test # unit tests (vitest)
(cd src-tauri && cargo test) # Rust tests
npm run build # type-check and build the frontendsrc/
main.ts app wiring: tabs, saving, file watching, shortcuts
render.ts markdown-it setup (Markdown to sanitized HTML)
preview.ts incremental preview updates, images, links, copy buttons
scrollsync.ts editor/preview scroll sync
editor.ts CodeMirror setup and theme
export.ts standalone HTML export
mermaid.ts lazy Mermaid rendering (+ WebKitGTK text-measurement workaround)
fonts.ts font settings panel
src-tauri/src/lib.rs Rust commands (fs, watcher, fonts, CLI args)
scripts/ install scripts
Releases are built by GitHub Actions (.github/workflows/release.yml):
-
Run
scripts/release.sh 0.2.0on an up-to-date, cleanmain. It sets the version inpackage.jsonandCargo.toml, runs the tests, commits, creates thev0.2.0tag, and then asks whether to push. -
Pushing the tag starts the Release workflow. It builds:
- Linux:
.deb,.rpm,.AppImageand a plain-binary.tar.gz - macOS: a universal
.dmg - Windows: an installer
.exeand a portable.exe
It attaches them all to a draft release, using the notes in
.github/release-notes.md. - Linux:
-
Check the draft under Releases, edit the notes, and click Publish.
The workflow refuses to build if the tag and the version files disagree. To rebuild an existing tag, run the workflow manually from the Actions tab and enter the tag.
- Platforms: x86-64 Linux and Windows, plus macOS on Intel and Apple Silicon. There are no ARM builds for Linux or Windows yet.
- Unsigned builds: the Windows and macOS builds aren't code-signed, so both systems warn on first launch. See Download.
- Install scripts: the scripts in
scripts/create a Linux desktop entry and are Linux-only. - Task-list checkboxes in the preview are read-only. Edit
[ ]/[x]in the source. - The sidebar lists only the current folder, not subfolders.
- Exported math loads its fonts from a CDN.
MIT © 2026 Timofey Klyubin










