Markwell
A minimal markdown viewer for macOS with Mermaid diagram support
Overview
Markwell is a small, focused utility for reading Markdown files on macOS. Open a .md file, read it in a clean large-panel view, and pick up where you left off from Recent files. Mermaid diagrams in fenced code blocks are rendered automatically. That's it — no accounts, no sync, no extras.
The scope was deliberately small. The goal was a tool that does one thing well, and a codebase that's genuinely credible as an open source project: proper CI, tests, security policies, and contributing documentation.
Why I Built It
I wanted to test the other end of the development spectrum. Building this website was a deliberate, multi-week process: documentation-first, custom design system, small careful iterations. Markwell was the experiment in the other direction — could I go from zero to a polished, published open source app in a single day, using Cursor, without sacrificing quality?
The constraints were real: tests, CI, linting, and the kind of scaffolding that makes a project credible for contributors — not a throwaway prototype.
What's Inside
Beyond the app itself, the repository includes everything you'd expect from a well-maintained open source project:
- GitHub Actions CI — Lint, format check, and tests on Ubuntu; a separate job builds the Mac app on
macos-latest - Security scanning —
npm audit --omit=dev --audit-level=criticalruns in CI so known critical vulnerabilities fail the build - Contributing guide — Run and build instructions, registry setup, code style, and how to submit changes
- Security policy — Responsible disclosure via GitHub's private vulnerability reporting
- MIT licence, CODE_OF_CONDUCT.md, SECURITY.md
- ESLint and Prettier configs
- Unit tests using Node's built-in test runner (
node --test)
Technical Decisions
Electron security was handled correctly from the start — context isolation enabled, Node integration disabled in the renderer:
webPreferences: {
preload: path.join(__dirname, 'electron', 'preload.js'),
contextIsolation: true,
nodeIntegration: false,
}Dependencies use tilde ranges (~x.y.z) so only patch updates are installed automatically — a deliberate choice for a desktop app where stability matters. No lockfile is committed, keeping the repo portable across registries.
Reflections
Speed and quality aren't mutually exclusive when the tooling can generate both the feature and the scaffolding simultaneously. For a small, well-scoped project like this, the overhead of "doing it properly" — CI, tests, docs — approaches zero when the AI handles the boilerplate.
The taste decisions were still mine: what to build, where to draw the scope boundary, whether to publish it. Cursor produced the structure and the prose; the voice and the decision to ship were human.
Read more about the build process in the accompanying blog post.