Desktop-first local workspace in the spirit of Notion: strict, minimal, offline-first, and built for serious writing and knowledge work.
Noir Note is a native desktop knowledge workspace with a custom Tauri shell, a block editor, nested pages, local SQLite persistence, and a structure that can grow toward sync, accounts, collaboration, exports, and plugins.
The current implementation is optimized for:
- fast local startup;
- keyboard-first editing;
- low visual noise;
- predictable persistence;
- clear separation between shell, UI, editor logic, and data layer.
- Tauri 2
- React 19
- TypeScript
- SQLite via
rusqlite
- Native desktop window for macOS, Windows, and Linux via Tauri
- Custom title bar and local-first workflow
- Sidebar with nested pages, search, and recent documents
- Block editor with slash commands, drag and drop, undo/redo, and autosave
- SQLite storage with migrations and repository-style data access
- Window state persistence and last-opened document restore
- Custom desktop shell and title bar
- Nested pages and recent documents
- Search-first sidebar with title, path, and content matches
- Block editor with slash commands
- Drag and drop blocks
- Undo and redo
- Local SQLite persistence with migrations
- Last opened page persistence
- Native window state persistence
Frontend:
src/components: desktop UI, editor, sidebar, and empty statessrc/hooks: workspace orchestration, hotkeys, and window state persistencesrc/services: pure logic for page tree, editor history, slash catalog, and Tauri bridgesrc/types: strict domain modelssrc/utils: editor and block helpers
Desktop and persistence:
src-tauri/src/lib.rs: Tauri bootstrap and command registrationsrc-tauri/src/db: SQLite migrations and repository layersrc-tauri/migrations: schema migrations forpages,blocks, andsettings
This split is intentional: UI remains replaceable, editor logic stays mostly pure, and the data layer is already shaped for future sync and account-backed storage.
.
├── src
│ ├── components
│ ├── hooks
│ ├── services
│ ├── types
│ └── utils
├── src-tauri
│ ├── migrations
│ └── src
│ └── db
├── tests
└── .github/workflows
Install dependencies:
npm installRun the frontend only:
npm run devRun the desktop app:
npm run tauri:devTypecheck, tests, and production frontend build:
npm run checkRun local quality checks:
cargo fmt --manifest-path src-tauri/Cargo.toml --checknpm run tauri:buildWindows installers from a Windows machine:
npm run tauri:build:windowsWindows NSIS installer only:
npm run tauri:build:windows:nsisCI runs:
npm run checkcargo fmt --checkcargo check
Release automation:
.github/workflows/windows-build.yml: validates that the app bundles on Windows.github/workflows/windows-release.yml: creates draft Windows releases fromv*tags
Ctrl/Cmd + K: focus page searchCtrl/Cmd + N: create pageCtrl/Cmd + Z: undoCtrl/Cmd + Shift + Z: redoType /: open block command flowAlt + ArrowUp/ArrowDown: move block
SQLite tables:
pages: tree structure, order, timestampsblocks: page-scoped ordered content blockssettings: recent pages, last opened page, and app-level state
This keeps the local model simple while leaving room for:
- authentication and remote identities;
- cloud sync;
- real-time collaboration;
- permissions;
- exports to Markdown/PDF;
- plugin hooks;
- database-style views.
Tauri on Linux needs system packages for GTK/WebKit and pkg-config.
Typical Debian/Ubuntu setup:
sudo apt install pkg-config libgtk-3-dev libwebkit2gtk-4.1-dev librsvg2-dev patchelf- page tree reordering and structural drag and drop
- markdown and PDF export
- sync engine and account layer
- collaboration-ready document operations
- plugin and command extension points
- The repository is configured to ship Windows installers via both
NSIS(-setup.exe) andWiX(.msi). - NSIS is configured for
currentUserinstalls to reduce elevation friction. - WiX uses a fixed
upgradeCode, so future releases upgrade in place instead of installing as a separate app. - WebView2 is bundled via the embedded bootstrapper mode, which avoids a hard dependency on a live internet connection during install while keeping installer size reasonable.