A fast, local-first Notion alternative built with Rust + Tauri. Block editor, nested pages, full-text search, black-and-white UI, ~115 MB RAM.
Svelte
58
37 commits
updated Oct 19, 2026
A fast, local-first notes workspace in the spirit of Notion: nested pages, a block editor, full-text search, databases, plus assignments, a calendar and a file library that all link together. It has a custom title bar, a vertical sidebar and a black-and-white look with optional accent colors. Built with Rust + Tauri 2 + TypeScript (Svelte 5 components).
| Thought Desk | Typical Electron notes app | |
|---|---|---|
| Installer / binary | ~4.4 MB exe | 80–200 MB |
| Memory, open | ~115 MB | 300–600 MB |
| Memory, minimized | ~95 MB | unchanged |
Private working set summed over all processes, measured on Windows 11 with the release build.
src-tauri/src/memory.rs.opt-level = "s", stripped, panic = "abort").Tested against a workspace of 7,500 pages (a 2 MB book among them), 2,000 files, 3,000 assignments and events, 11,000 open to-dos and 17,000 flashcards:
Databases were tested the same way: a 50,000-row tracker linked to a 5,000-row one, 40 smaller databases, notes on thousands of rows and 100,000 edits:
/, Ctrl+K, Home), and you're set. All of it can be changed in Settings, which can also show the welcome again. People who used the app before don't see it.Ctrl+Shift+\ (an empty side offers recent pages and a search). Or drag: a page from the sidebar onto the right half opens it beside, onto the left opens it there; drag the side pane's header to the left (or the page's name in the title bar to the right) to swap sides or move the open page over. Drag the divider to resize (double-click evens it out), swap sides, or move the side page to the main view. The split and its width are remembered; on a narrow window the side hides until there's room. Page margins follow each pane's width.$x^2$ for a formula in a sentence, $$ then Space for one on its own line, or press Ctrl+Shift+E (it turns selected text into math). Click a formula to edit it in place; it updates as you type and keeps its last good form while a command is half-typed. Typing \ suggests commands with a preview, Tab moves between the empty {} slots a suggestion leaves (and then out of the group), braces close themselves, and a Symbols palette has structures, Greek letters, operators, relations and arrows (it wraps selected LaTeX, e.g. into \sqrt{…}). Arrow keys stop on a formula so Enter edits it; Backspace in an empty one removes it. Chemistry works too (\ce{2H2 + O2 -> 2H2O}).\( \), \[ \], $ $ or $$ $$ (ChatGPT's copy button, a .md or .tex file) brings it in typeset along with its headings, lists, bold and code, while prices like "$5 and $10" stay text; pasted KaTeX or MathML pages (ChatGPT, Wikipedia) keep their LaTeX. Flashcards can hold formulas on either side, search finds a formula's LaTeX, Markdown export writes $…$ / $$…$$, and Word export turns every formula into a real, editable Word equation. KaTeX loads the first time a page shows math, with only its woff2 fonts bundled./ command menu with fuzzy matching, and Markdown shortcuts (#, -, 1., [], >, ```, ---).⋮⋮ to move it, click it for Turn into / Duplicate / Move / Delete, or press + to insert below./page), and inline page links (@) that stay in sync when pages are renamed..csv (column types are guessed: numbers, dates, checkboxes, choices, links), or paste rows straight from a spreadsheet. Every row is also a page, with room for notes under its properties; the first picture in it becomes its gallery cover.{Price} * {Qty} or if({Done}, "✓", ""), with 53 functions for logic, math, text, dates and lists. The editor autocompletes properties and functions, explains each one, and shows the result for a real row as you type; renaming a property updates the formulas that use it.Enter or just start typing to edit, Tab, Shift+arrows to select, Ctrl+C / Ctrl+V, Ctrl+D fills down, Delete clears, Ctrl+Enter opens the row), column summaries (sum, average, count, percent checked…), drag cards between board columns, drag rows to reorder, filters for every type, with dates like "this week" or "within the next 7 days", and its own undo and redo./database puts a new one inside a page and /linked database shows an existing one there, with its own view. Rows with a date show on the Calendar and can be dragged to another day, Ctrl+K finds rows by any value, course, tag and file properties use the app's own courses, tags and library, and databases share Trash, Favorites, Duplicate and CSV export with pages.Ctrl+Shift+Space (even while the app is in the background) or the box on Home. Save a to-do or a note to your Inbox page, or an assignment or event straight to the planner.#tag search..ics file from Canvas, Google Calendar or Outlook (Calendar → Import, Settings, or Ctrl+K). A preview lets you pick what to import and whether each entry is an event or an assignment. Time zones are converted, weekly "Mon/Wed/Fri" classes become one repeat per weekday, skipped and moved sessions carry over, and Canvas "Title [Course]" entries are matched to courses (created if needed). Importing the same file again updates instead of duplicating./flashcard in any page for a card with a front and a back (Enter moves to the back, then on to the next card, so a whole deck can be typed in one go). Every page with cards is a deck; the Flashcards view (Ctrl+5) groups decks by course and shows what's due, new and mastered. Study sessions use spaced repetition (Again / Hard / Good / Easy, keys 1–4, Space to flip), so each card comes back just before you'd forget it. Study buttons sit on the deck's page, its course and Home's summary..docx to Downloads, with Word heading styles, lists, to-dos, tables, images, code and flashcards, ready to hand in. Markdown export is still there too.@ links a page to pages, assignments, events or files (assignment chips show a live check and due date); /assignment, /event and /file create or insert them from a page; a notes page links back to its assignment; due assignments show in the calendar; files dropped anywhere land in the library.Ctrl+K over pages (SQLite FTS5 with prefix matching and a substring fallback), assignments, events and files, with quick Go to and Create actions.| Keys | Action |
|---|---|
Ctrl+K / Ctrl+P | Search (with text selected in the editor, Ctrl+K adds a link) |
Ctrl+N | New page |
Ctrl+Shift+Space | Quick Capture (system-wide when enabled in Settings) |
Ctrl+1 … Ctrl+5 | Home / Assignments / Calendar / Files / Flashcards |
← / →, T | Calendar: previous or next month or week, today |
Ctrl+\ | Toggle sidebar |
Ctrl+Shift+\ | Split view |
Alt+← / Alt+→, mouse back/forward | Navigate history |
Ctrl+Shift+L | Toggle dark mode |
Ctrl+, | Settings |
Ctrl+/ | Every shortcut on one sheet |
Ctrl+Shift+E | Inline math (or turn the selection into math) |
Ctrl+D | Duplicate block |
Ctrl+Click on a link | Open in browser |
Ctrl+Z / Ctrl+Y in a database | Undo / redo database edits |
These are the defaults; every app shortcut can be changed in Settings → Keyboard Shortcuts.
Requirements: Node 20+, Rust (stable, MSVC toolchain on Windows), WebView2 runtime (preinstalled on Windows 10/11).
git clone https://github.com/kusule1351-hue/thought-desk.git
cd thought-desk
npm install
npm run app # desktop app with hot reload (tauri dev)
npm run dev # UI only, in a browser, with an in-memory fake backend
npm run check # type-check the frontend
npm run bundle # release build + Windows installer
cd src-tauri && cargo test # storage tests
cd src-tauri && cargo test --release stress -- --ignored --nocapture --exact stress::stress # heavy-workspace benchmark
cd src-tauri && cargo test --release stress_databases -- --ignored --nocapture # 55,000-row database benchmark
Everything lives in one SQLite database (thoughtdesk.db, WAL mode) plus a files/ folder for the file library (stored under random names; the database keeps their real names). On Windows that's %APPDATA%\app.thoughtdesk.desktop\, and Settings → Storage shows the exact path. Back up that folder to back up your notes.
Set THOUGHTDESK_DATA_DIR to use a different folder, e.g. a portable copy on a USB drive.
Ready for sync. Databases are stored so that two copies can later be merged without a server deciding who wins. Each install has a device id; every edit to a cell, property, view, automation or row's title, icon, place or deletion carries a hybrid logical clock stamp, and changed records are queued in an outbox. Merging keeps the newest stamp per cell, so two people editing different cells of the same row both keep their edits; deleted properties and views stay as tombstones so a deletion can't be undone by an older copy. Row order uses fractional keys, so moving a row never renumbers the others. The sync_pending / sync_apply / sync_sent commands are the hooks an online service will use (src-tauri/src/sync.rs, databases.rs). Page bodies and the rest of the workspace aren't stamped yet.
src/ TypeScript + Svelte UI
App.svelte shell, global shortcuts, window show/close handling
lib/store.svelte.ts page tree state, navigation history (pages and views), debounced saving
lib/planner.svelte.ts courses, assignments and events
lib/library.svelte.ts the file library
lib/tags.svelte.ts tags; lib/todos.svelte.ts to-dos rolled up from pages; lib/capture.ts Quick Capture
lib/databases.svelte.ts databases: rows, values, saving, undo, import and export
lib/db/ database views (table, board, gallery, list, calendar, chart, timeline, form), pickers, formula
language, query engine (filters, sorts, groups), templates, CSV, order keys
lib/editor/ TipTap editor: slash menu, @-links, block handle, callouts, file blocks…
lib/views/ Home, Assignments, Calendar (month and week), Files and tag pages
lib/sheets/ assignment and event editors, file preview
lib/components/ sidebar, title bar, search, settings, trash, menus
lib/ui/ shared controls: segmented control, switch, swatches, rows…
dev-mock.ts fake backend for `npm run dev` (dev only, not bundled)
src-tauri/src/
db.rs SQLite schema and migrations, page tree, trash, FTS search (+ tests)
planner.rs courses, assignments, events (+ tests)
library.rs file library: import, rename, usage (+ tests)
organize.rs tags, backlinks, to-dos rolled up from pages (+ tests)
commands.rs Tauri commands
cards.rs flashcards: decks, reviews (+ tests)
databases.rs database schemas, properties, views, automations, rows and templates, merging copies (+ tests)
sync.rs device id, hybrid logical clocks, outbox
files.rs `tdfile://` protocol (byte ranges), stray-file cleanup
stress.rs heavy-workspace benchmark (`cargo test --release stress -- --ignored`)
memory.rs WebView2 suspend/trim while minimized, idle, or after Settings
Copyright (C) 2026 Kusule
Thought Desk is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. If you distribute a modified version, or let people use one over a network, you must make its source code available under the same license.
The interface uses Inter by Rasmus Andersson, bundled under the SIL Open Font License 1.1.
A fast, local-first Notion alternative built with Rust + Tauri. Block editor, nested pages, full-text search, black-and-white UI, ~115 MB RAM.
Svelte
58
37 commits
updated Oct 19, 2026
A fast, local-first notes workspace in the spirit of Notion: nested pages, a block editor, full-text search, databases, plus assignments, a calendar and a file library that all link together. It has a custom title bar, a vertical sidebar and a black-and-white look with optional accent colors. Built with Rust + Tauri 2 + TypeScript (Svelte 5 components).
| Thought Desk | Typical Electron notes app | |
|---|---|---|
| Installer / binary | ~4.4 MB exe | 80–200 MB |
| Memory, open | ~115 MB | 300–600 MB |
| Memory, minimized | ~95 MB | unchanged |
Private working set summed over all processes, measured on Windows 11 with the release build.
src-tauri/src/memory.rs.opt-level = "s", stripped, panic = "abort").Tested against a workspace of 7,500 pages (a 2 MB book among them), 2,000 files, 3,000 assignments and events, 11,000 open to-dos and 17,000 flashcards:
Databases were tested the same way: a 50,000-row tracker linked to a 5,000-row one, 40 smaller databases, notes on thousands of rows and 100,000 edits:
/, Ctrl+K, Home), and you're set. All of it can be changed in Settings, which can also show the welcome again. People who used the app before don't see it.Ctrl+Shift+\ (an empty side offers recent pages and a search). Or drag: a page from the sidebar onto the right half opens it beside, onto the left opens it there; drag the side pane's header to the left (or the page's name in the title bar to the right) to swap sides or move the open page over. Drag the divider to resize (double-click evens it out), swap sides, or move the side page to the main view. The split and its width are remembered; on a narrow window the side hides until there's room. Page margins follow each pane's width.$x^2$ for a formula in a sentence, $$ then Space for one on its own line, or press Ctrl+Shift+E (it turns selected text into math). Click a formula to edit it in place; it updates as you type and keeps its last good form while a command is half-typed. Typing \ suggests commands with a preview, Tab moves between the empty {} slots a suggestion leaves (and then out of the group), braces close themselves, and a Symbols palette has structures, Greek letters, operators, relations and arrows (it wraps selected LaTeX, e.g. into \sqrt{…}). Arrow keys stop on a formula so Enter edits it; Backspace in an empty one removes it. Chemistry works too (\ce{2H2 + O2 -> 2H2O}).\( \), \[ \], $ $ or $$ $$ (ChatGPT's copy button, a .md or .tex file) brings it in typeset along with its headings, lists, bold and code, while prices like "$5 and $10" stay text; pasted KaTeX or MathML pages (ChatGPT, Wikipedia) keep their LaTeX. Flashcards can hold formulas on either side, search finds a formula's LaTeX, Markdown export writes $…$ / $$…$$, and Word export turns every formula into a real, editable Word equation. KaTeX loads the first time a page shows math, with only its woff2 fonts bundled./ command menu with fuzzy matching, and Markdown shortcuts (#, -, 1., [], >, ```, ---).⋮⋮ to move it, click it for Turn into / Duplicate / Move / Delete, or press + to insert below./page), and inline page links (@) that stay in sync when pages are renamed..csv (column types are guessed: numbers, dates, checkboxes, choices, links), or paste rows straight from a spreadsheet. Every row is also a page, with room for notes under its properties; the first picture in it becomes its gallery cover.{Price} * {Qty} or if({Done}, "✓", ""), with 53 functions for logic, math, text, dates and lists. The editor autocompletes properties and functions, explains each one, and shows the result for a real row as you type; renaming a property updates the formulas that use it.Enter or just start typing to edit, Tab, Shift+arrows to select, Ctrl+C / Ctrl+V, Ctrl+D fills down, Delete clears, Ctrl+Enter opens the row), column summaries (sum, average, count, percent checked…), drag cards between board columns, drag rows to reorder, filters for every type, with dates like "this week" or "within the next 7 days", and its own undo and redo./database puts a new one inside a page and /linked database shows an existing one there, with its own view. Rows with a date show on the Calendar and can be dragged to another day, Ctrl+K finds rows by any value, course, tag and file properties use the app's own courses, tags and library, and databases share Trash, Favorites, Duplicate and CSV export with pages.Ctrl+Shift+Space (even while the app is in the background) or the box on Home. Save a to-do or a note to your Inbox page, or an assignment or event straight to the planner.#tag search..ics file from Canvas, Google Calendar or Outlook (Calendar → Import, Settings, or Ctrl+K). A preview lets you pick what to import and whether each entry is an event or an assignment. Time zones are converted, weekly "Mon/Wed/Fri" classes become one repeat per weekday, skipped and moved sessions carry over, and Canvas "Title [Course]" entries are matched to courses (created if needed). Importing the same file again updates instead of duplicating./flashcard in any page for a card with a front and a back (Enter moves to the back, then on to the next card, so a whole deck can be typed in one go). Every page with cards is a deck; the Flashcards view (Ctrl+5) groups decks by course and shows what's due, new and mastered. Study sessions use spaced repetition (Again / Hard / Good / Easy, keys 1–4, Space to flip), so each card comes back just before you'd forget it. Study buttons sit on the deck's page, its course and Home's summary..docx to Downloads, with Word heading styles, lists, to-dos, tables, images, code and flashcards, ready to hand in. Markdown export is still there too.@ links a page to pages, assignments, events or files (assignment chips show a live check and due date); /assignment, /event and /file create or insert them from a page; a notes page links back to its assignment; due assignments show in the calendar; files dropped anywhere land in the library.Ctrl+K over pages (SQLite FTS5 with prefix matching and a substring fallback), assignments, events and files, with quick Go to and Create actions.| Keys | Action |
|---|---|
Ctrl+K / Ctrl+P | Search (with text selected in the editor, Ctrl+K adds a link) |
Ctrl+N | New page |
Ctrl+Shift+Space | Quick Capture (system-wide when enabled in Settings) |
Ctrl+1 … Ctrl+5 | Home / Assignments / Calendar / Files / Flashcards |
← / →, T | Calendar: previous or next month or week, today |
Ctrl+\ | Toggle sidebar |
Ctrl+Shift+\ | Split view |
Alt+← / Alt+→, mouse back/forward | Navigate history |
Ctrl+Shift+L | Toggle dark mode |
Ctrl+, | Settings |
Ctrl+/ | Every shortcut on one sheet |
Ctrl+Shift+E | Inline math (or turn the selection into math) |
Ctrl+D | Duplicate block |
Ctrl+Click on a link | Open in browser |
Ctrl+Z / Ctrl+Y in a database | Undo / redo database edits |
These are the defaults; every app shortcut can be changed in Settings → Keyboard Shortcuts.
Requirements: Node 20+, Rust (stable, MSVC toolchain on Windows), WebView2 runtime (preinstalled on Windows 10/11).
git clone https://github.com/kusule1351-hue/thought-desk.git
cd thought-desk
npm install
npm run app # desktop app with hot reload (tauri dev)
npm run dev # UI only, in a browser, with an in-memory fake backend
npm run check # type-check the frontend
npm run bundle # release build + Windows installer
cd src-tauri && cargo test # storage tests
cd src-tauri && cargo test --release stress -- --ignored --nocapture --exact stress::stress # heavy-workspace benchmark
cd src-tauri && cargo test --release stress_databases -- --ignored --nocapture # 55,000-row database benchmark
Everything lives in one SQLite database (thoughtdesk.db, WAL mode) plus a files/ folder for the file library (stored under random names; the database keeps their real names). On Windows that's %APPDATA%\app.thoughtdesk.desktop\, and Settings → Storage shows the exact path. Back up that folder to back up your notes.
Set THOUGHTDESK_DATA_DIR to use a different folder, e.g. a portable copy on a USB drive.
Ready for sync. Databases are stored so that two copies can later be merged without a server deciding who wins. Each install has a device id; every edit to a cell, property, view, automation or row's title, icon, place or deletion carries a hybrid logical clock stamp, and changed records are queued in an outbox. Merging keeps the newest stamp per cell, so two people editing different cells of the same row both keep their edits; deleted properties and views stay as tombstones so a deletion can't be undone by an older copy. Row order uses fractional keys, so moving a row never renumbers the others. The sync_pending / sync_apply / sync_sent commands are the hooks an online service will use (src-tauri/src/sync.rs, databases.rs). Page bodies and the rest of the workspace aren't stamped yet.
src/ TypeScript + Svelte UI
App.svelte shell, global shortcuts, window show/close handling
lib/store.svelte.ts page tree state, navigation history (pages and views), debounced saving
lib/planner.svelte.ts courses, assignments and events
lib/library.svelte.ts the file library
lib/tags.svelte.ts tags; lib/todos.svelte.ts to-dos rolled up from pages; lib/capture.ts Quick Capture
lib/databases.svelte.ts databases: rows, values, saving, undo, import and export
lib/db/ database views (table, board, gallery, list, calendar, chart, timeline, form), pickers, formula
language, query engine (filters, sorts, groups), templates, CSV, order keys
lib/editor/ TipTap editor: slash menu, @-links, block handle, callouts, file blocks…
lib/views/ Home, Assignments, Calendar (month and week), Files and tag pages
lib/sheets/ assignment and event editors, file preview
lib/components/ sidebar, title bar, search, settings, trash, menus
lib/ui/ shared controls: segmented control, switch, swatches, rows…
dev-mock.ts fake backend for `npm run dev` (dev only, not bundled)
src-tauri/src/
db.rs SQLite schema and migrations, page tree, trash, FTS search (+ tests)
planner.rs courses, assignments, events (+ tests)
library.rs file library: import, rename, usage (+ tests)
organize.rs tags, backlinks, to-dos rolled up from pages (+ tests)
commands.rs Tauri commands
cards.rs flashcards: decks, reviews (+ tests)
databases.rs database schemas, properties, views, automations, rows and templates, merging copies (+ tests)
sync.rs device id, hybrid logical clocks, outbox
files.rs `tdfile://` protocol (byte ranges), stray-file cleanup
stress.rs heavy-workspace benchmark (`cargo test --release stress -- --ignored`)
memory.rs WebView2 suspend/trim while minimized, idle, or after Settings
Copyright (C) 2026 Kusule
Thought Desk is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. If you distribute a modified version, or let people use one over a network, you must make its source code available under the same license.
The interface uses Inter by Rasmus Andersson, bundled under the SIL Open Font License 1.1.