Back to Articles

MarkdownPad: When 'Nothing Else' Is the Entire Point

[ View on GitHub ]

MarkdownPad: When 'Nothing Else' Is the Entire Point

Hook

In an era where text editors compete to become full IDEs, one developer asked: what if we just stopped adding features?

Context

The markdown editor landscape suffers from an identity crisis. Tools like VS Code and Obsidian have evolved into Swiss Army knives—plugins for everything, knowledge graphs, git integration, cloud sync, AI assistants. Even dedicated markdown editors feel compelled to add Kanban boards, spreadsheet support, and database integrations. This feature accumulation isn't inherently bad, but it creates a void: where do you turn when you just need to edit a README?

MarkdownPad emerges from this void with an almost aggressive simplicity. Built by Max Rousseau, it's a macOS application that opens markdown files, lets you edit them, and saves them. The repository description literally ends with 'Nothing else.' This isn't a feature gap waiting to be filled—it's a philosophical stance. In the tradition of classic Mac applications like TextEdit or the original Notepad, MarkdownPad treats restraint as a feature, not a limitation.

Technical Insight

Renderer Process

Electron Main Process

Edit Markdown

Raw Markdown

AST/HTML

Detect Diagrams

Rendered SVG

Save Request

Load File

Restore Session

Persist Preferences

Mode Switch

Mode Switch

User Input

File System Manager

State Persistence

Window Controller

Edit Mode

Text Editor

Markdown Parser

remark/marked

View Mode

HTML Renderer

Mermaid.js

Diagram Engine

System architecture — auto-generated

Under the hood, MarkdownPad is an Electron application written in TypeScript, which immediately raises eyebrows given its minimalist positioning. Why choose Electron's notorious memory overhead for a tool that prides itself on simplicity? The answer lies in development velocity and cross-platform rendering consistency. Building native macOS apps in Swift/AppKit requires deep platform knowledge and creates markdown rendering challenges—you'd need to implement your own parser or bridge to existing libraries awkwardly. Electron lets you leverage the entire npm ecosystem while maintaining a cohesive TypeScript codebase.

The architecture employs a dual-mode system rather than the split-pane preview most developers expect. You're either in edit mode (working with raw markdown syntax) or view mode (seeing the rendered output). This might seem regressive, but it's deliberate. Split-pane previews create cognitive overhead—your eyes constantly dart between source and output, and the editor must synchronize scroll positions, handle cursor mapping between panes, and manage two rendering contexts simultaneously. MarkdownPad's approach is: edit, then see the result. It mirrors the mental model of markdown itself—write in plain text, render when needed.

Here's what a minimal Electron main process for this architecture might look like:

import { app, BrowserWindow, ipcMain } from 'electron';
import { readFile, writeFile } from 'fs/promises';
import path from 'path';

const windows = new Map<string, BrowserWindow>();

function createEditorWindow(filePath?: string) {
  const win = new BrowserWindow({
    width: 800,
    height: 600,
    titleBarStyle: 'hidden',
    trafficLightPosition: { x: 16, y: 16 },
    webPreferences: {
      nodeIntegration: false,
      contextIsolation: true,
      preload: path.join(__dirname, 'preload.js')
    }
  });

  if (filePath) {
    windows.set(filePath, win);
    win.loadFile('index.html', { query: { file: filePath } });
  } else {
    win.loadFile('index.html');
  }

  win.on('closed', () => {
    if (filePath) windows.delete(filePath);
  });
}

ipcMain.handle('file:read', async (event, filePath) => {
  const content = await readFile(filePath, 'utf-8');
  return content;
});

ipcMain.handle('file:save', async (event, filePath, content) => {
  await writeFile(filePath, content, 'utf-8');
  return true;
});

app.on('open-file', (event, filePath) => {
  event.preventDefault();
  if (windows.has(filePath)) {
    windows.get(filePath)?.focus();
  } else {
    createEditorWindow(filePath);
  }
});

This pattern—one window per file—is distinctly Mac-like. Instead of tabs that let you accumulate 47 open documents, each markdown file gets its own window. You can use macOS's native window management (Mission Control, Spaces, Stage Manager) rather than fighting with in-app tab systems. The windows Map prevents opening the same file twice, and the open-file event hooks into macOS's document handling so double-clicking a .md file in Finder does the right thing.

The view mode rendering likely uses a library like marked or remark with GitHub Flavored Markdown extensions. The repository mentions Mermaid diagram support, which means injecting the mermaid.js library and calling mermaid.init() after rendering:

import { marked } from 'marked';
import mermaid from 'mermaid';

function renderMarkdown(source: string): string {
  const html = marked.parse(source, { 
    gfm: true,
    breaks: true 
  });
  
  // Inject rendered HTML into DOM
  const container = document.getElementById('preview');
  if (container) {
    container.innerHTML = html;
    // Initialize Mermaid diagrams
    mermaid.init(undefined, container.querySelectorAll('.language-mermaid'));
  }
  
  return html;
}

The interactive task-list feature is particularly clever. Standard markdown renders - [ ] Task as a checkbox, but it's just HTML—clicking does nothing. MarkdownPad adds event listeners to these checkboxes that modify the underlying markdown source:

container.querySelectorAll('input[type="checkbox"]').forEach((checkbox, index) => {
  checkbox.addEventListener('change', (e) => {
    const checked = (e.target as HTMLInputElement).checked;
    const lines = currentSource.split('\n');
    let taskCount = 0;
    
    for (let i = 0; i < lines.length; i++) {
      if (/^\s*[-*]\s+\[([ x])\]/.test(lines[i])) {
        if (taskCount === index) {
          lines[i] = lines[i].replace(/\[([ x])\]/, checked ? '[x]' : '[ ]');
          break;
        }
        taskCount++;
      }
    }
    
    currentSource = lines.join('\n');
    markDirty(); // Trigger save indicator
  });
});

This bridges view and edit modes elegantly—you can check off tasks without switching modes, but the source truth remains the markdown text. The session restoration feature uses Electron's state management to persist open files and window positions, recreating your workspace on app launch. It's the kind of polish that separates a weekend project from a daily-driver tool.

Gotcha

The Electron foundation is both a strength and weakness. While it enables rapid development and consistent markdown rendering, it means MarkdownPad ships with an entire Chromium browser. A simple text editor shouldn't consume 150+ MB of memory, but Electron apps do. If you're on an 8GB MacBook Air with dozens of apps open, this overhead accumulates quickly. Native Swift alternatives like MaCHO or even AppleScript-based solutions would be far lighter, though they'd sacrifice the npm ecosystem and cross-platform potential.

The single-star GitHub status is concerning for production use. No stars doesn't mean bad code, but it signals minimal community testing, no bug reports from diverse use cases, and uncertain maintenance. If you encounter a rendering edge case or a macOS Sonoma compatibility issue, you're likely filing the first bug report—and waiting for a solo maintainer to respond. For critical documentation workflows, this risk might be unacceptable.

The lack of split-pane preview will frustrate users coming from MacDown, Typora, or VS Code. Toggling between edit and view modes adds friction, especially when formatting tables or debugging complex nested lists where you need immediate visual feedback. The app also appears to lack vim keybindings, Emacs modes, or any editor customization beyond themes—if you have muscle memory for modal editing, you'll fight the textarea constantly.

Verdict

Use MarkdownPad if you value focus over features and you're tired of markdown editors that want to manage your entire life. It's perfect for quick README edits, maintaining documentation in existing repositories, or writing markdown without the cognitive overhead of plugin ecosystems and customization paralysis. The multi-window approach works beautifully if you embrace macOS's native window management instead of fighting it. Skip it if you need battle-tested stability for professional work (that one-star count is a red flag), require real-time split-pane preview for complex formatting, or run on constrained hardware where Electron's memory footprint matters. Also skip if you want any extensibility—there's no plugin system, and 'nothing else' means nothing else. For most developers, MacDown or Typora offer better feature-to-complexity ratios, but if minimalism itself is the feature you're seeking, MarkdownPad delivers exactly what it promises: markdown editing, and nothing else.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/developer-tools/max-rousseau-markdownpad.svg)](https://starlog.is/api/badge-click/developer-tools/max-rousseau-markdownpad)