Most productivity tools feel like databases. Phing is different. It is a local-first, deeply aesthetic knowledge manager built for researchers, writers, and students who want their digital workspace to feel as calming as a quiet desk with a cup of tea.
Instead of overwhelming you with features, Phing focuses on emotional UX, robust typography, and an interface that respects your focus. Every architectural decision — from the debounce pipeline to the atomic write strategy — exists to give you one guarantee: your thoughts are never lost.
Ready to create your peaceful workspace? You can download the latest version of Phing directly from our releases page:
Supported Platforms:
- 🍏 macOS (Apple Silicon / M1, M2, M3): Download the
.dmgor.app.tar.gzfile (e.g.,phing_x.x.x_aarch64.dmg). - 🍏 macOS (Intel / x86): Download the specific Intel build (e.g.,
phing_x.x.x_x64.dmg).
Note for macOS Users: If you encounter a 'damaged and cannot be opened' error, please see the note below regarding Apple's Gatekeeper.
- ☁️ Calm by Design: Soft typography (Lora & LINE Seed Sans), frosted-glass surfaces (
backdrop-filter), and zero-latency Zen modes. The interface steps back so your thinking can step forward. - 🔒 Bulletproof Trust: Every note and mind map flows through a hardened persistence pipeline — debounce coalescing, a per-document
WriteQueue, pre-write snapshot archiving, and atomic.tmp → renamecommits. A crash at any point leaves your vault intact. A destructive action in-session is reversible with⌘Z. A destructive action across sessions is recoverable from.phing/snapshots/. Trust is not a feature, it is the foundation. - 🧠 Visual Thinking: A deeply integrated Mind Map Board where every document has its own independently tracked, undo-capable history. Scoped per-document undo stacks — not global middleware — mean switching between maps never bleeds history, and
⌘Zon the board never accidentally touches your note editor state. - ⌨️ Keyboard First: A seamless Command Palette workflow, comprehensive board navigation with spatial arrow-key awareness, and formatting shortcuts that keep your hands exactly where they should be.
Phing's persistence layer is engineered to the same standard as professional document editors. Here is exactly what protects your data:
Every mutation — whether a keystroke, a label rename, or a board reset — travels through the same hardened pipeline:
store mutation (synchronous, in-memory)
↓
100 ms debounce — coalesces rapid bursts into a single write
↓
WriteQueue — per-document serialisation; concurrent writes for the same ID are impossible
↓
captureSnapshot — archives current disk content to .phing/snapshots/ before overwriting
↓
atomic write — content lands in a .tmp sibling first, then renamed over the target
↓
vault on disk
No write ever reaches disk synchronously. No two writes for the same document ever run concurrently. A crash between the .tmp write and the rename leaves a recoverable orphan, not a corrupted file.
The WriteQueue serialises writes strictly per document ID. If a move operation (moveNote) arrives while a debounced title-rename write is already inflight for the same note, the move is queued behind it — never run concurrently. The move's run() closure re-reads filePath at execution time so it always operates on the file's actual current on-disk location, regardless of what preceding queue entries may have done.
Before any folder or pocket is sent to the OS Trash, Phing pre-emptively disarms every pending write for notes inside it: debounce timers are cancelled via clearTimeout, and queued-but-not-yet-inflight write entries are dropped via WriteQueue.cancel(). Without this, a timer firing after trash_file would call mkdir() on the trashed parent and silently recreate it on disk.
A board reset — or any other operation that irrevocably destroys document state — triggers two independent safety mechanisms simultaneously:
- In-session undo stack —
pushUndosnapshots the completeMindMapNodetree and node-selection state synchronously before the mutation runs.⌘Zrestores it instantly, with selection restored to the exact node that was active at the time. - Durable snapshot archive —
saveMindMapDoccallscaptureSnapshotbefore every overwrite, writing the previous disk content to.phing/snapshots/as a timestamped.bakfile. Up to 10 snapshots are retained per document; the oldest are pruned automatically. This archive survives application restarts, meaning a reset committed in a session that has since ended is still recoverable manually.
Phing watches the vault for external modifications (other editors, iCloud Drive, Google Drive). When a filesystem change event arrives, the on-disk content is hashed using FNV-1a 32-bit and compared against a hash of the current in-memory state. A difference surfaces the ConflictDialogue, offering three resolution paths: reload from disk, keep local, or dismiss. Phing's own atomic writes are excluded from triggering false positives via a per-write suppression window registered on vaultWatcher immediately before each write.
On every vault open, findOrphanedTmpFiles walks the vault recursively and collects any .md.tmp (note) or .json.tmp (mind-map document) files left by a crash mid-write. For each orphan: if the final path is missing, the .tmp is renamed to complete the interrupted write; if the final path already exists, the stale .tmp is removed. This runs silently before the vault loads.
The undo/redo system uses two module-level Map<string, UndoEntry[]> structures keyed by MindMapDoc.id, giving every document a fully independent, isolated history of up to 50 steps. Global Zustand middleware (such as zundo) was explicitly rejected: middleware snapshots the entire store slice — including UI state like editingId and notePopupId — causing incorrect selections to be restored on undo. The manual stack approach gives precise control over exactly what is undoable: tree structure and node selection only.
Crafted with obsessive attention to detail using:
- Tauri v2 for a lightweight, native-feeling desktop shell with a Rust backend.
- React 19 & TypeScript for the interactive surface.
- Zustand 5 for fast, fine-grained, independently scoped state management.
- Tiptap for the rich Markdown editing experience, extended with custom keyboard shortcuts, wiki-links, and footnotes.
- React Flow for the node-based Mind Map canvas with automatic radial layout.
- Framer Motion for spring-animated UI transitions.
- Phase 1 (Reliability & Trust Layer): 🟢 Completed. Atomic writes, WriteQueue serialisation, per-document Mind Map undo/redo, dual-layer snapshot recovery, deletion safety guards, FNV-1a conflict detection, and crash-orphan recovery are all in production.
- Phase 2 (Performance & Invisible Speed): 🟡 In Progress. Currently optimising large mind map virtualisation and heavy UI dynamics.
These shortcuts work from any view.
| Shortcut | Action |
|---|---|
⌘K |
Open / close Command Palette |
⌘⇧M |
Toggle between Notes view ↔ Mind Map Board |
⌘⇧S |
Collapse / expand the main sidebar |
These shortcuts are active when the Notes view is open (not the Mind Map Board).
| Shortcut | Action |
|---|---|
⌘N |
Create a new note |
⌘⇧Z |
Toggle Zen mode (distraction-free full screen) |
⌘⇧A |
Toggle Academic mode (A4 paper layout) |
⌘⇧B |
Toggle Backlinks panel |
⌘⌫ |
Delete selected note — press twice within 3 seconds to confirm |
Standard Tiptap / browser shortcuts are included for completeness.
| Shortcut | Action |
|---|---|
⌘F |
Open / close the in-note Find bar |
Esc |
Close the Find bar |
⌘B |
Toggle bold |
⌘I |
Toggle italic |
⌘U |
Toggle underline |
⌘⇧X |
Toggle |
⌘E |
Toggle inline code |
⌘1 – ⌘5 |
Toggle Heading 1 through 5 |
⌘- |
Insert a horizontal rule |
⌘Z / ⌘⇧Z |
Undo / Redo (native editor history) |
[[ |
Open wiki-link suggestion popup |
The floating formatting toolbar is draggable via the ⠿ grip handle. Double-click the handle to snap it back to its default position.
Open the board with ⌘⇧M. The board manages its own shortcut scope — global note shortcuts are suspended while it is active.
| Shortcut | Action |
|---|---|
Tab |
Add a child node to the selected node |
↵ Enter |
Add a sibling node after the selected node |
Space |
Begin editing the selected node's label inline |
Del / ⌫ |
Delete the selected node and its entire subtree |
⌘⇧N |
Open / close the rich-text note pane attached to the selected node |
| Shortcut | Action |
|---|---|
⌘Z |
Undo last tree mutation (scoped to the active map document) |
⌘⇧Z |
Redo |
Note: Undo history is isolated per map document and survives map switching. Up to 50 steps are retained.
⌘Zand⌘⇧Zremain active even while the note pane is open — the pane manages its own independent text-editing undo.
Arrow-key navigation is context-aware and respects the radial branch layout.
| Shortcut | Action |
|---|---|
→ |
Move to the nearest child (or parent if current branch faces left) |
← |
Move to the parent (or nearest child if current branch faces right) |
↑ |
Move to the visual sibling above |
↓ |
Move to the visual sibling below |
| Feature | How to access |
|---|---|
| Command Palette | ⌘K — search notes, switch views, run actions |
| Zen Mode | ⌘⇧Z — hides all chrome; press again to exit |
| Academic Mode | ⌘⇧A — constrains the editor to an A4-width card |
| Backlinks Panel | ⌘⇧B — shows all notes that link to the current one via [[wiki links]] |
| Mind Map PDF Export | Toolbar button on the Board — fits the canvas to A4 landscape and exports via native save dialogue |
| Note PDF Export | Toolbar button in the Editor — paginates the note surface to multi-page A4 portrait |
Phing is a passion project built during late nights after law lectures. If this app helps you find your focus or brings a little peace to your digital workspace, consider supporting its development!
🇹🇭 สำหรับผู้ใช้งานชาวไทย (PromptPay):
หากน้องผิงช่วยให้การจดโน้ตหรือการค้นคว้าของคุณราบรื่นและสงบขึ้น สามารถสนับสนุนค่ากาแฟเล็กๆ น้อยๆ ผ่านการสแกนคิวอาร์โค้ดด้านล่างได้เลยนะคะ ขอบคุณที่เอ็นดูโปรเจกต์นี้ค่ะ 💖
If you encounter a 'damaged and cannot be opened' error when launching the app, this is due to macOS Gatekeeper blocking applications not signed with an Apple Developer Certificate. You can safely bypass this by running the following command in your Terminal:
xattr -cr /Applications/phing.app(Please ensure the app is moved to your /Applications folder before running this command.)
Phing is open-sourced software generously licensed under the MIT license. Feel free to use, modify, and build upon it to create your own peaceful workspace!





