I Built a Markdown Editor in a Weekend Because Every Other One Annoyed Me
Source: Dev.to
I didn’t plan to build a markdown editor this weekend
I was working on something else, and somewhere in the middle of it I opened my markdown editor to take notes. My annoyance with every markdown editor I’ve tried finally reached a head.
Not annoyed in the “this is broken” sense.
Annoyed in the “why does this app need a cloud account and fourteen features I’ll never use” sense. Every alternative I tried had the same problem in different packaging — too expensive, too bloated, or too clever.
So I opened Claude Code and started building one.
What I built
- Three panes – file browser on the left, editor in the middle, live preview on the right.
- Tabs for multiple open files.
- Session restore – close the app, reopen it, everything’s still there.
- Dark mode.
- Search & replace.
- Formatting toolbar for the things I always forget the syntax for.
That’s it. No cloud sync, no collaboration, no plugin architecture; just markdown files on my computer, edited in a clean interface.

The stack
- Electron 33
- React 18
- CodeMirror 6
- marked for GFM rendering
- Vite 6 for the build
- electron‑builder for packaging
Why the first version was usable in under an hour
Not because AI is magic. Because the AI had context.
I use a governance‑first development workflow: before any code gets written, the AI agent has access to persistent architecture documents, wireframes, a personal coding style guide, personal design guidelines, and detailed specifications. These files survive across sessions and context‑window compaction.
The prompt describes what to build. The governance documents describe how to build it, and to what standard.
That’s the difference between “a thing that kind of works” and “a thing I’m actually using that same day.”
It wasn’t perfect on the first pass, but it was functional enough that I was taking notes in it within the first hour. Then I started tweaking.
(And I wrote this post using it.)
The interesting technical bits
Bidirectional scroll sync
The naive percentage‑based approach breaks when the editor and preview have different content heights. I built section‑based anchor mapping instead: the editor and preview each maintain a map of heading positions, and scrolling either pane updates the other by interpolating between anchor points. Both directions stay aligned regardless of content‑length differences.
Smart formatting toolbar
Each button doesn’t just apply formatting — it first checks whether the cursor is already inside that formatting and toggles it off.
- Heading buttons cycle through H1 → H2 → H3 → paragraph.
- List buttons handle multi‑line selections and continue numbering from preceding items.
Small details that make the toolbar feel considered rather than tacked on.
External change detection
A requirement of the original spec that resurfaced later during code review. Edit a file in another app while it’s open in the editor, and you get a full diff view showing exactly what changed. Options:
- Keep your version.
- Accept the external changes.
- Save as a new file.
No silent overwrites. I’d completely forgotten I’d added it until I triggered it accidentally and thought, “oh, that’s actually amazing.”

Session restore
Open tabs, active tab, folder path, scroll positions, and window size/position all persist across app restarts.
- Multi‑window support (
Cmd+Shift+N) – each window preserves its own state. - Close the app, open it tomorrow — everything’s exactly where you left it.
The security wake‑up call
After the features were working, I ran an adversarial code review on the codebase – a separate Claude Code instance with its own repo, its own governance documents, read‑only access to the target code, and zero shared context with the building agent. Its only job was to find everything wrong.
What it found was embarrassing in the best way.
The worst finding wasn’t missing security – it was the ceremony of security without the substance. contextBridge, contextIsolation: true, proper cleanup functions – all present, all technically correct, and all masking a straight pipeline from a malicious .md file to arbitrary filesystem access. The sandbox: false with a wrong justification comment was the cherry on top.
It’s exactly the kind of thing that survives review after review because it sounds right, and nobody actually traces the dependency to verify it.
Specific fixes
- XSS prevention –
DOMPurifysanitizes all markdown before rendering in the preview pane. - Sandbox enabled – Chromium sandbox and context isolation enforced on all windows.
- Filesystem access control – Path validation limits access to the home directory and
/Volumes; sensitive directories (.ssh,.gnupg,.aws) are blocked. - Path‑traversal protection –
local-resource://protocol restricted to image file extensions. - Content Security Policy – tightened CSP on settings.
That’s the whole story: a tiny, focused markdown editor built in an hour with AI assistance, refined by a governance‑first workflow, and hardened after a rigorous security review.
nd update dialogs
URL scheme allowlisting
shell.openExternal is limited to https://, http://, and mailto:.
Security fixes
- Twenty‑plus security fixes across eleven versions.
- This highlights a concern with the current wave of AI‑generated code being shipped without independent review—technically functional apps with exploitable security models, because the same agent that writes the code is also the only one evaluating it.
Release cadence
Thirty‑one versions in two days
- v0.1.0 → v0.1.31 released over a weekend.
- Not rushed—thanks to a governance‑first pattern where each feature lands cleanly, gets tested, is committed, and the next one starts from solid ground.
App details
- Signed and notarized with Apple.
- Auto‑updates from GitHub Releases.
- Handles file associations (appears in Finder’s Open With menu for
.md,.markdown,.mdx,.txt). - Restores all windows with their tabs and folder paths on relaunch.
What it deliberately doesn’t do
- No cloud sync.
- No collaboration.
- No Vim mode.
- No WYSIWYG.
- No plugin system.
- No account creation.
- No subscription.
- No telemetry.
Every markdown editor eventually tries to become a knowledge‑management platform. This one won’t.
- The filesystem is the organizational layer.
- Git is the version control.
- Markdown is the format—portable, readable, owned by you.
The editor simply makes working with those files fast and pleasant. Your files are plain markdown on disk. Open them with anything, anywhere, forever.
Try it
- Still beta – v0.1.x – but functional.
- Problems? Probably; I’ll find them while dog‑fooding.
- It satisfies my use case, and that’s good enough for now.
Code: (MIT licensed, macOS only)
Download: Grab the .dmg from Releases –
- Signed and notarized, no Gatekeeper warnings.
- macOS 12+ required, Apple Silicon supported.
If you live in markdown and every editor you’ve tried wants to be something it shouldn’t be—this one doesn’t.