A simple and elegant Markdown Viewer built with Qt6.
PlainMD is partially vibe-coded with OpenCode: Kimi K2.5 Turbo / Kimi K2.6 🤖
- Native Qt6 markdown rendering - Fast, native rendering without external dependencies
- File browser sidebar - Browse and open markdown files with a tree view
- Multiple format support - Markdown (.md), MDX (.mdx), and plain text (.txt)
- Drag and drop support - Open files and folders by dragging them into the window
- Recent files & folders - Quick access to recently opened files and folders with separate history and privacy toggles
- Auto-reload on file change - Detects external file modifications and prompts to reload
- Manual reload - Force a refresh of the current file with F5 (useful when auto-reload is missed or you want to clear caches)
- File tree / Sidebar - Show/hide sidebar with F9 or status bar button. Right-click any file to copy its path or reveal it in Explorer/File Manager. Right-click any folder to copy its path or open it in Explorer
- Zen Mode - Distraction-free reading at the press of
F11. Hides sidebar, toolbar, status bar, and menu bar for a pure document view. PressF11again orEscapeto restore everything exactly as it was - Navigation History - Go back and forward through recently viewed files with
Alt+←/Alt+→or toolbar buttons. Session-only (never saved to disk). Optional privacy toggle in Preferences - Document Outline - Left
QTabWidget(tabs at bottom) with Files/Outline panes. Outline scans headings from the rendered document and shows them hierarchically; click any heading to jump to it in the document - Minimap - Document overview with color-coded content types (images, headings, lists, links, code blocks) and viewport highlight; toggle with F10 or status bar button. Plain text (.txt) and MDX files show simplified minimap without markdown-specific coloring
- Status bar - Shows word count, zoom level, file type, encoding (auto-detected UTF-8 or ANSI), line endings (CRLF/LF), word wrap toggle, and quick-toggle buttons for file tree and minimap
- Zoom controls - Zoom in/out with Ctrl++ and Ctrl+-
- Word wrap toggle - Toggle line wrapping with Ctrl+W or status bar button
- Find/Search - Search within documents with Ctrl+F, find next with F3
- Search in Files - Search across all markdown files in the loaded folder with Ctrl+Shift+F. Shows match count per file, snippet preview, and highlights first occurrence when opened
- Print & Export - Print to physical printer or export directly to PDF (with better emoji support)
- Copy File/Folder Path - Right-click any file or folder in the sidebar to copy its full path to the clipboard (with native path separators)
- Copy Code - Right-click on code blocks or inline code to copy to clipboard with custom context menu
- Customizable fonts - Configure editor font and emoji print font
- Window title format - Choose between filename only or full path in window title
- Privacy options - Toggle external image loading, recent files/folders history, last opened file, and last opened folder memory independently
- Folder protection - Blocks opening root drives and system folders (Windows, Program Files, /usr, etc.) to prevent UI freezing; warns when opening empty folders; shows progress indicator while scanning
- URL tooltips - Hover over links to see the resolved absolute path
- YAML frontmatter display - Shows frontmatter as a code block
- Windows 10 or later (64-bit)
- Visual C++ Redistributable 2022 (most systems already have this installed)
Note: If PlainMD fails to start with a missing DLL error, install the Visual C++ Redistributable from the link above. This is a one-time system requirement.
- Qt 6.x runtime libraries
- Standard desktop environment (X11 or Wayland)
- Qt 6.x (with Qt6Core, Qt6Gui, Qt6Widgets, Qt6Network, Qt6PrintSupport)
- C++17 compatible compiler
Quick build using provided scripts:
:: Build
build.bat
:: Clean build artifacts
clean.bat
:: Deploy Qt dependencies (after building)
windeployqt release\plainmd.exeManual build:
:: Setup MSVC environment (or run vcvarsall.bat x64 directly)
setenv.bat
:: Generate build files and build
qmake plainmd.pro && nmake
:: Deploy Qt dependencies
windeployqt release\plainmd.exe
:: Create installer (optional, requires Inno Setup)
:: Output: dist\plainmd-<version>-x64-setup.exe
build-installer.bat
:: Create portable ZIP (optional)
:: Output: dist\plainmd-<version>-x64-portable.zip
build-zip.bat
:: All-in-one release build (optional)
:: Output: dist\plainmd-<version>-release.zip
build-release.batEditor integration: Build tasks are configured for Zed (.zed/tasks.json) and VS Code (.vscode/tasks.json) for integrated development.
Quick build using provided scripts:
# Build release binary
./build.sh
# Clean build artifacts
./clean.shManual build:
# Install dependencies (Debian/Ubuntu)
sudo apt install qt6-base-dev build-essential
# Generate build files and build
qmake plainmd.pro && make
# Output: release/plainmd
# Create .deb package (Debian/Ubuntu, optional)
# Output: dist/plainmd_<version>_amd64.deb
./build-deb.sh
# Create AppImage (universal Linux, optional)
# Output: dist/plainmd-<version>-x86_64.AppImage
./build-appimage.sh
# Create Flatpak (optional, requires flatpak-builder)
# Output: dist/plainmd-<version>-<arch>.flatpak
./build-flatpak.sh
# All-in-one release build (optional)
# Output: dist/plainmd-<version>-linux-release.zip
./build-release.sh- File Menu → Open File (Ctrl+O) or Open Folder (Ctrl+Shift+O)
- Drag and drop files or folders into the window
- Command line:
plainmd <file.md>orplainmd <folder/> - Double-click .md files (after file association on Windows)
- File tree on the left shows all markdown files in the current folder
- Recent files in the File menu for quick access
- Click any file in the tree to view it instantly
| Shortcut | Action |
|---|---|
| Ctrl+O | Open file |
| Ctrl+Shift+O | Open folder |
| Ctrl+F | Find in document |
| F3 | Find next |
| Ctrl+Shift+F | Search in files |
| F5 | Reload current file |
| F9 | Toggle file tree |
| F10 | Toggle minimap |
| Ctrl+W | Toggle word wrap |
| Ctrl+P | |
| Ctrl+Shift+P | Export to PDF |
| Ctrl+, | Preferences |
| Ctrl++ | Zoom in |
| Ctrl+- | Zoom out |
| Ctrl+0 | Reset zoom |
| Esc | Clear search highlight |
Access preferences via View → Preferences (Ctrl+,):
- Editor Font - Main text font
- Emoji Print Font - Font for emoji characters when printing (use a Nerd Font for best results)
- External Editor - Path to your preferred external editor
- Window Title - Choose between filename only or full path format
- Privacy - Toggle external image preview, recent files/folders history, last opened file, and last opened folder memory independently
Color emoji fonts (like Segoe UI Emoji) may not render correctly when printing to PDF. To fix this:
- Install a Nerd Font (e.g., "CaskaydiaCove Nerd Font", "JetBrainsMono Nerd Font")
- Open Preferences → Editor
- Set "Emoji Print Font" to your Nerd Font
- Check "Use for emoji printing"
- Now emojis will print correctly as monochrome glyphs
- Single-window desktop app - Entry:
src/main.cpp→MainWindow - Qt6 native rendering - Uses
QTextEdit::setMarkdown()for rendering (no external parser) - File system model -
QFileSystemModelwrapped withFilterProxyModelfor file tree - Auto-reload -
QFileSystemWatchermonitors loaded files for external changes; manual reload via F5 unconditionally re-runsloadFile() - Document outline - Left
QTabWidget(tabs at bottom) with Files/Outline panes. Outline deferred viaQTimer::singleShotaftersetMarkdown()so Qt's async heading format assignment finishes before scanning - Settings -
QSettings(IniFormat) for preferences persistence
PlainMD/
├── src/ # Source code
│ ├── main.cpp
│ ├── mainwindow.cpp/h # Main window and UI
│ ├── preferencesdialog.cpp/h/ui # Preferences dialog
│ ├── finddialog.cpp/h/ui # Find in document dialog
│ ├── searchindialog.cpp/h/ui # Search in files dialog
│ ├── aboutdialog.cpp/h/ui # About dialog with license viewer
│ ├── licensedialog.cpp/h/ui # License viewer dialog
│ ├── minimap.cpp/h # Document minimap widget
│ └── filterproxymodel.cpp/h # File tree filtering
├── images/ # Application icons (Tabler Icons)
├── samples/ # Sample markdown files
├── .zed/ # Zed Editor configuration
│ └── tasks.json # Build tasks for Zed
├── .vscode/ # VS Code configuration
│ └── tasks.json # Build tasks for VS Code
├── plainmd.pro # qmake project file
├── plainmd.qrc # Qt resources
├── plainmd.rc # Windows resources
├── build.sh # Linux build script
├── clean.sh # Linux clean script
├── build-deb.sh # Debian package builder (outputs to dist/)
├── install-deb.sh # Debian install helper
├── uninstall-deb.sh # Debian uninstall helper
├── build-appimage.sh # AppImage builder (outputs to dist/)
├── build-flatpak.sh # Flatpak builder (outputs to dist/)
├── uninstall-flatpak.sh # Remove Flatpak from system
├── build-release.sh # Linux all-in-one release pipeline
├── make-checksums.sh # Generate SHA256 checksums (Linux)
├── archive-release.sh # Create versioned archive of dist/ (Linux)
├── build.bat # Windows build script
├── clean.bat # Windows clean script
├── setenv.bat # Set up MSVC environment
├── build-installer.bat # Windows installer builder (outputs to dist/)
├── build-zip.bat # Windows portable ZIP builder (outputs to dist/)
├── build-release.bat # Windows all-in-one release pipeline
├── make-checksums.bat # Generate SHA256 checksums (Windows)
├── archive-release.bat # Create versioned archive of dist/ (Windows)
├── dist/ # Distribution packages (.exe, .zip, .deb, .AppImage, .flatpak, .sha256)
├── installer.iss # Inno Setup installer script
├── eu.brainbytez.plainmd.yaml # Flatpak manifest
├── .gitattributes # Git line ending rules (for WSL/cross-platform dev)
├── README.md # User documentation
└── AGENTS.md # Developer documentation
GPLv3 License - See LICENSE file for details.
- Icons by Tabler Icons (MIT License)
- Built with Qt6
Happy markdown viewing! 📄✨

