Skip to content

viyaleta/markdown-monster

Repository files navigation

Markdown Monster

Markdown Monster is a minimal, elegant Markdown editor built for Mac. It is designed to stay out of your way and let you focus on writing. Open a file, edit in a clean distraction-free environment, and preview your rendered Markdown instantly.

This application was built entirely using Cursor, an AI-powered code editor, as an experiment in AI-assisted desktop application development. The full build, including debugging, iteration, and polish, consumed the following estimated resources:

Category Estimate
Input tokens (cumulative across all turns) ~1,000,000 - 1,500,000
Output tokens (responses and tool calls) ~150,000 - 250,000
Thinking/reasoning tokens ~300,000 - 500,000
Total tokens processed ~1.5 - 2.2 million
Low estimate High estimate
Raw electricity 1 kWh 3 kWh
With cooling overhead 1.2 kWh 3.6 kWh
Energy cost ~$0.07 ~$0.45

For context, that is roughly equivalent to running a microwave for one to three minutes, or about ten to thirty Google searches per turn.

Features

  • Full Markdown rendering with GitHub Flavored Markdown support, including tables, task lists, fenced code blocks, and strikethrough.
  • Dual-mode interface that lets you switch between a rich preview and a syntax-highlighted source editor with a single click or keyboard shortcut.
  • Floating format toolbar that appears when you select text, offering bold, italic, code, strikethrough, link insertion, and heading levels (H1 through H4).
  • Custom search bar that works in both preview and editor modes. In preview mode it highlights matches directly in the rendered output. In editor mode it uses the CodeMirror search engine.
  • Quick-edit popups in preview mode. Right-click any block to edit its Markdown source inline without switching to the full editor.
  • Image drag-and-drop with options to embed as base64, save to a relative folder, or reference by absolute path.
  • Image preview support for local files, including filenames with spaces and special characters, via a custom protocol handler.
  • Multi-window support. Open as many documents as you need simultaneously. Each window has independent state, file tracking, and dirty indicators.
  • Export to PDF and HTML.
  • Action icon strip in the top-right corner for quick access to view toggle, export, copy, and search.
  • Links in the preview open in your default browser, not inside the app window.
  • Remembers window size, recent files, and user preferences between sessions.
  • File associations for .md and .markdown files, with full "Open With" integration on macOS.

Tech Stack

  • Electron for the desktop shell and native OS integration.
  • CodeMirror 6 for the source editor with Markdown syntax highlighting, bracket matching, search, and line wrapping.
  • markdown-it for Markdown-to-HTML rendering with source position mapping for quick-edit functionality.
  • esbuild for fast bundling of the renderer process.
  • electron-builder for packaging and distribution as .app, .dmg, and .zip.

Installation

There are several ways to install Markdown Monster.

From a DMG (recommended)

  • Download the latest .dmg file from the GitHub Releases page. Choose the arm64 version for Apple Silicon Macs or the x64 version for Intel Macs.
  • Open the DMG and drag Markdown Monster to your Applications folder.
  • Launch it from Applications or Spotlight.

From source

  • Clone the repository and install dependencies:
git clone https://github.com/your-username/markdown-monster.git
cd markdown-monster
npm install
  • Run the app in development mode:
npm start
  • To build a packaged .app and .dmg:
npm run dist
  • The built application will be in the dist/mac-arm64/ or dist/mac-x64/ directory. Copy Markdown Monster.app to /Applications.

Using the install script

  • If you have a built DMG available locally or from a release, you can use the included install script:
bash scripts/install.sh

Registering file associations

After installing the .app to /Applications, register it with macOS so it appears in "Open With" menus:

/System/Library/Frameworks/CoreServices.framework/Frameworks/LaunchServices.framework/Support/lsregister -f "/Applications/Markdown Monster.app"

To make Markdown Monster the default editor for .md files, right-click any .md file in Finder, select Get Info, choose Markdown Monster under "Open with", and click Change All.

Editor integration (Cursor, VS Code, Windsurf)

The project includes a lightweight extension that adds an "Open with Markdown Monster" option to the right-click context menu in Cursor, VS Code, and Windsurf. It works in the file explorer sidebar, inside an open editor tab, and on tab headers.

To install, first build the .vsix package from the project directory:

cd vscode-extension
npx @vscode/vsce package --allow-missing-repository

Then install the generated .vsix into each editor:

# Cursor
/Applications/Cursor.app/Contents/Resources/app/bin/cursor --install-extension vscode-extension/markdown-monster-opener-1.0.0.vsix

# VS Code
code --install-extension vscode-extension/markdown-monster-opener-1.0.0.vsix

# Windsurf
/Applications/Windsurf.app/Contents/Resources/app/bin/windsurf --install-extension vscode-extension/markdown-monster-opener-1.0.0.vsix

After installing, reload the editor (Cmd+Shift+P, then "Developer: Reload Window"). Right-click any .md or .markdown file and you will see "Open with Markdown Monster" in the context menu.

The extension requires the Markdown Monster .app to be installed in /Applications. The source is in the vscode-extension/ directory.

Usage

Opening files

  • Launch the app to see the welcome screen with options to create a new document or open an existing file.
  • Use Cmd+O to open a file or Cmd+N to create a new document. Each opens in its own window.
  • Drag and drop .md files onto the app icon or right-click a file in Finder and choose "Open With" to open it directly.

Editing

  • Double-click anywhere in the preview to switch to the editor.
  • Select text in the editor to see the floating format toolbar with options for headings, bold, italic, code, links, and strikethrough.
  • Right-click any block in preview mode to open a quick-edit popup for that section without leaving the preview.

Images

  • Drag and drop an image file into the editor. You will be prompted to choose how to handle it: embed as base64, save to a relative images folder, or use the absolute file path.
  • Images with local absolute paths render correctly in the preview, including filenames with spaces.

Searching

  • Press Cmd+F to open the search bar at the top of the window. It works in both preview and editor modes.
  • Type to search. Press Enter to go to the next match, Shift+Enter for the previous match.
  • In preview mode, matches are highlighted directly in the rendered output with smooth scrolling to each match.

Exporting

  • Use the export icon in the top-right action strip or the File menu to export your document as PDF or HTML.
  • The "Copy as Markdown" option in the export dropdown copies the raw Markdown source to your clipboard.

Keyboard shortcuts

  • Cmd+N: New document (new window)
  • Cmd+O: Open file
  • Cmd+S: Save
  • Cmd+Shift+S: Save As
  • Cmd+Shift+P: Toggle preview
  • Cmd+Shift+E: Toggle editor
  • Cmd+B: Bold
  • Cmd+I: Italic
  • Cmd+K: Insert link
  • Cmd+`: Inline code
  • Cmd+Shift+X: Strikethrough
  • Cmd+F: Search
  • Cmd+E: Export as PDF
  • Cmd+P: Print
  • Cmd+,: Preferences

Developer Guide

Project structure

  • main.js -- Electron main process. Handles window creation, menus, IPC handlers, file operations, the custom local-file:// protocol for serving local images, and multi-window state management.
  • preload.js -- IPC bridge that exposes a safe window.api object to the renderer using context isolation.
  • renderer/app.js -- Main renderer entry point. Coordinates all UI modules, manages application state, and handles the search bar, action strip, link popup, drag-and-drop, and IPC communication.
  • renderer/editor.js -- CodeMirror 6 setup with Markdown syntax highlighting, custom keybindings, selection tracking, programmatic search, and text manipulation functions.
  • renderer/preview.js -- Markdown rendering with markdown-it, source line mapping for quick-edit, image path rewriting for the custom protocol, and preprocessing for filenames with spaces.
  • renderer/toolbar.js -- Floating format toolbar with heading dropdown.
  • renderer/quick-edit.js -- Inline quick-edit popup for editing Markdown blocks from preview mode.
  • renderer/settings.js -- Preferences panel for default view, image handling mode, and images folder.
  • renderer/styles.css -- All application styles.
  • renderer/index.html -- HTML shell with search bar, action strip, toolbar, link popup, settings modal, and shortcuts modal.
  • lib/file-handler.js -- File read/write operations and settings persistence.
  • lib/export.js -- PDF and HTML export logic.
  • lib/image-handler.js -- Image processing for drag-and-drop (base64 embedding, relative copy, absolute path).
  • build.js -- esbuild configuration for bundling the renderer.
  • scripts/install.sh -- Shell script for automated installation from a DMG.
  • scripts/patch-dev-name.sh -- Patches the Electron development binary so the macOS menu bar shows "Markdown Monster" instead of "Electron".
  • vscode-extension/ -- Lightweight VS Code extension that adds "Open with Markdown Monster" to the right-click context menu. Works with Cursor, VS Code, and Windsurf.

Development workflow

  • Run npm start to build the bundle and launch the app.
  • Run npm run dev to start esbuild in watch mode alongside the Electron process. Changes to renderer files will be rebundled automatically; reload the window with Cmd+R to see them.
  • The renderer bundle is output to dist/bundle.js. The main process and preload scripts run directly without bundling.
  • After making changes, run npm run dist to produce a packaged .app and .dmg for distribution.

Architecture notes

  • The main process and renderer communicate exclusively through IPC channels defined in preload.js. The renderer has no direct access to Node.js APIs.
  • Context isolation is enabled. All Node.js functionality is exposed through the window.api bridge.
  • A custom local-file:// protocol is registered in the main process to serve local image files securely, bypassing Electron's cross-origin restrictions on file:// URLs.
  • Each window maintains independent state (file path, dirty flag) tracked in a Map keyed by window ID. Menu actions and IPC handlers resolve the correct window using BrowserWindow.getFocusedWindow() or BrowserWindow.fromWebContents().
  • The Content Security Policy in index.html allows self, inline styles, and images from self, data:, file:, and local-file: sources.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors