MarkUP GitHub

MarkUP Desktop

An editor for MarkUP documents: a file tree, tabs, an editor with completion and diagnostics from the MarkUP language service, and a live preview. It is a Tauri application (Rust and the system WebView) with a React front end.

Windows installers are listed in Installation.

Building from source

In a browser (no native toolchain; files are kept in browser storage, with sample documents):

npm install
npm run dev -w @markup-lang/desktop     # http://localhost:1420

As a desktop app you also need Rust and, on Windows, the Visual Studio Desktop development with C++ workload including a Windows SDK; on Linux the Tauri prerequisites.

npm run app:dev -w @markup-lang/desktop     # development window with hot reload
npm run app:build -w @markup-lang/desktop   # installers in src-tauri/target/release/bundle

If Rust cannot find the MSVC linker on Windows, run the commands from a Developer PowerShell for VS.

The installer associates .markup and .mkup files with the app; opening one opens its folder with the file in a tab.

The window

The menu bar (File, Edit, View, Go, Help) lists every command with its shortcut; Alt or F10 moves the focus to it. The sidebar has four tabs — Files, Search, Outline and Problems — and Ctrl+B hides it. Editor and preview share the rest of the window; the status bar shows the folder, the file, problem counts, the cursor position and a word count.

  • Files — the folder's files. Right-click for New File, New Folder, Rename (F2), Delete (to the system trash), Copy Path. Files with errors or warnings are colored and counted.
  • Tabs — each keeps its own undo history and selection. Middle-click closes. A dot marks unsaved changes; you are always asked before unsaved work is discarded.
  • Editor — highlighting, errors, completion and hover all come from the MarkUP language service (the same one used by VS Code): type ::: for components, { for attributes, ](# for headings. Ctrl+. applies a quick fix, F12 or Ctrl+Click goes to a definition.
  • Formatting bar — above the editor: bold (**text**), italic, underline (:u[text]), strikethrough, bulleted list, checkbox (- [ ] task), link, pie chart and Insert component. Each button writes real MarkUP and toggles: applied to formatted text it removes the format. With a selection it formats each selected line, leaving list, quote and heading markers alone; with only a cursor it formats the word under it, or inserts a selected placeholder. The same actions are in the command palette (Toggle Bold, Toggle Checkbox, Insert Pie Chart…).
  • Preview — renders as you type and scrolls with the editor. Double-click an element to jump to its source. Links to other documents open them in a tab.
  • Layouts — editor only, split, preview only (Ctrl+Alt+1/2/3, or cycle with Ctrl+\). Drag the divider to resize.
  • Search (Ctrl+Shift+F) across the folder with case, whole-word and regular-expression options.
  • Outline — headings and components of the current file, following the cursor.
  • Problems (Ctrl+Shift+M) — every error and warning in the folder.
  • Document graph (Ctrl+Shift+G, or the graph button in Files) — every MarkUP file as a dot, every link between two files ([text](guide.markup), reference links, href of components such as card) as a line. Links to files that do not exist are drawn as dashed dots. Scroll to zoom, drag the background to pan, drag a document to place it (it stays there; right-click releases it), click a document to open it. The graph follows edits, new and deleted files as they happen; Esc goes back to the editor.
  • Command palette (Ctrl+Shift+P) and quick open (Ctrl+P). In quick open, > switches to commands, @ to headings, : to a line number.
  • Export to HTML (Ctrl+Shift+S) — a standalone page with the theme.
  • Settings (Ctrl+,) — theme (dark, light, system), preview theme, font size, tab size, word wrap, line numbers, scroll sync, auto save. The shortcut list is in the same dialog.

Files changed outside the app are reloaded automatically when they have no unsaved edits; otherwise the tab is marked and saving overwrites the external change.

Keyboard shortcuts

Command paletteCtrl+Shift+P, F1
Quick open fileCtrl+P
Go to heading or componentCtrl+Shift+O
Go to lineCtrl+G
Insert componentCtrl+Alt+I
Find in fileCtrl+F
Search in folderCtrl+Shift+F
Save / save allCtrl+S / Ctrl+Alt+S
New fileCtrl+N
Open folderCtrl+O
Close tabCtrl+W
Next / previous tabCtrl+Tab / Ctrl+Shift+Tab
Toggle sidebarCtrl+B
Explorer / outline / problemsCtrl+Shift+E / Ctrl+Shift+U / Ctrl+Shift+M
Document graphCtrl+Shift+G
Editor / split / previewCtrl+Alt+1 / 2 / 3, cycle Ctrl+\
Font sizeCtrl+= / Ctrl+- / Ctrl+0
SettingsCtrl+,
Quick fix / go to definitionCtrl+. / F12

On macOS use ⌘ instead of Ctrl.

How it is built

src/
  fs/          WorkspaceFs: Tauri implementation and an in-memory one for the browser
  state/       store (useSyncExternalStore), workbench actions, commands, settings
  editor/      CodeMirror integration with the language service, formatting commands
  graph/       document graph model and force layout
  components/  React UI
src-tauri/     Rust: workspace-scoped file commands, watcher, trash, dialogs

The Rust side is deliberately small: it only reads and writes files inside the opened folder (paths are canonicalised and checked), writes atomically, deletes to the trash, watches for changes and exports HTML through a save dialog. All language work happens in the front end with the shared packages.

The content security policy keeps 'unsafe-inline' for styles and sets dangerousDisableAssetCspModification: ["style-src"]. Without it, Tauri adds a nonce to style-src, which makes the webview ignore 'unsafe-inline' and block the stylesheet CodeMirror injects at run time — the editor then loses its layout and the text no longer lines up with the line numbers. Scripts keep Tauri's nonces and hashes.

See ADR 0004 for why Tauri, React and CodeMirror.