Skip to content

Repository files navigation

MonkiNotes

MonkiNotes

A super lightweight note taking app that feels native everywhere.

A free, open source, offline-first notes app for macOS, Windows and Linux — with a Finder-style column browser, unlimited folder nesting, a rich text editor, instant full-text search, and optional Google Drive sync. No account, no subscription, no telemetry.

License: MIT Electron Platforms


Why another notes app

Most note apps ask you to adopt their sync service, their account, and their file format before you can write a sentence. MonkiNotes does the opposite:

  • Your notes are a file you own. One SQLite database on your disk. No account, no server, no telemetry.
  • The cloud is opt-in. Google Drive sync exists, is off by default, and runs against your OAuth client — nothing routes through a third party.
  • It stays out of the way. No editor framework, no UI kit, no toolbar clutter. The window is a browser, an editor, and a status line.
  • It looks like it belongs. Native menus, native context menus, native dialogs, platform keyboard conventions, and a strictly neutral light/dark palette.

Features

Folders that nest as deep as you want

The browser is a Miller column view, the same interaction Finder uses. Click a folder and its contents open in the next column to the right — at any depth.

Crucially, the browser never shows more than five columns at once. Going deeper scrolls the window rightwards; clicking back into an earlier column re-renders the columns behind it and drops everything to its right. A ten-level hierarchy stays as readable as a two-level one.

  • Drag the divider between columns to widen or narrow either side
  • Drag items between columns to re-file them; drop onto a folder row to move inside it
  • ← steps back up the hierarchy, Enter renames, Delete removes
  • Cycles are impossible — a folder can't be dropped into its own descendant
  • Deleting a folder removes its subtree in a single cascading transaction

Right-click anywhere to create

Right-click a row or the empty space of any column to get a native menu with New Note and New Folder, created in that column. Item menus add open, rename, duplicate, export, and delete. There is no "new" button anywhere in the chrome, and no starter document — the app opens empty and stays that way until you write something.

Rich text editing

A proper rich text editor with an icon toolbar — bold, italic, underline, strikethrough, two heading levels, body text, bulleted and numbered lists, quote, code block, link, image, and clear formatting. Buttons light up to show what's active at the caret.

Drag and drop images straight into a note, or paste them from the clipboard, or pick them with the image button. Images are written to an attachments folder beside the database and referenced through a private monki:// URL scheme rather than being inlined as base64, so the database stays small and syncs quickly.

Notes autosave 400 ms after you stop typing, and any pending edit is flushed before you switch notes — there is no save button and nothing to lose.

Search

Every note is indexed with SQLite FTS5 over a tag-stripped copy of its text, so results match prose rather than markup. Press ⌘F / Ctrl+F and results appear as you type, ranked by BM25, each showing its folder path and a matching snippet. Picking a result expands every column along its path to reveal it.

Light and dark, chosen by you

Two explicit themes, switched in Settings → Appearance. The app deliberately does not follow the system appearance — the theme is your choice and it sticks. The palette is entirely neutral: greys, white, and near-black, with no brand colour anywhere in the UI. The focused folder or note is marked with a white selection chip.

Screenshots

Five columns of hierarchy and a rich text note, side by side:

MonkiNotes in dark mode

The same window in light mode — the theme is an explicit choice, not the system's:

MonkiNotes in light mode

Settings: theme, editor text size, and your own Google Drive credentials:

MonkiNotes settings

Installation

macOS — one command (recommended)

curl -fsSL https://raw.githubusercontent.com/mishenThakshana/monkiNotes/main/install.sh | bash

Picks the right build for Apple silicon or Intel, installs it to /Applications and opens it. Use this rather than the .dmg: curl downloads are not quarantined by macOS, so the app just launches — no security dialog and nothing to click through.

From a release

Grab the installer for your platform from the Releases page:

Platform File
macOS (Apple silicon & Intel) MonkiNotes-<version>-<arch>.dmg
Windows MonkiNotes Setup <version>.exe (or the portable .exe)
Linux .AppImage, .deb, or .rpm

macOS: prefer the one-line installer above. If you take the .dmg from a browser instead, macOS quarantines it and — because the build is unsigned — reports it as "MonkiNotes is damaged and can't be opened". The app is fine; clear the flag once after moving it to Applications:

xattr -dr com.apple.quarantine /Applications/MonkiNotes.app

Right-click → Open does not clear this particular dialog; the command above is the fix.

From source

git clone https://github.com/mishenThakshana/monkiNotes.git
cd monkiNotes
npm install     # also rebuilds better-sqlite3 against Electron's ABI
npm run dev     # hot-reloading development app

Requires Node.js 20+. On Linux you'll need the usual native build toolchain (build-essential, python3) for better-sqlite3.

Usage

Action macOS Windows / Linux
New note / folder right-click any column, or ⌘N / ⇧⌘N right-click, or Ctrl+N / Ctrl+Shift+N
Search all notes ⌘F Ctrl+F
Rename selection Enter Enter
Delete selection ⌫ Delete
Go up a level ← ←
Bold / italic / underline ⌘B ⌘I ⌘U Ctrl+B Ctrl+I Ctrl+U
Export note as HTML ⇧⌘E Ctrl+Shift+E
Sync now ⌘S Ctrl+S
Settings ⌘, Ctrl+,

Google Drive sync

Sync is off until you turn it on, and MonkiNotes deliberately ships without an embedded Google client — an OAuth secret in a public repository is not a secret. You create a client in your own Google Cloud project, which means the app talks to Google as you, and your notes never touch infrastructure belonging to this project.

One-time setup

  1. Open the Google Cloud Console and create a project.
  2. APIs & Services → Library → Google Drive API → Enable.
  3. OAuth consent screen → External → add your own Google account as a test user. The only scope needed is drive.appdata, which is non-sensitive.
  4. Credentials → Create credentials → OAuth client ID → Desktop app.
  5. In MonkiNotes: Settings → Google Drive sync, paste the client ID and secret, then Connect Google Drive. Your browser opens for consent and hands the app back a token.

How it works

  • Sign-in uses the OAuth 2.0 loopback flow with PKCE. The redirect lands on a short-lived 127.0.0.1 listener; the authorisation code is bound to a one-time verifier.
  • The refresh token is encrypted with Electron's safeStorage, which is backed by the macOS Keychain, Windows DPAPI, or your Linux keyring.
  • The database is snapshotted into Drive's appDataFolder — a hidden per-app folder. It does not appear in your Drive, and no other app (including anything else you build) can read it.
  • Each side carries a revision stamp. On sync the newer revision wins: newer locally pushes, newer remotely pulls and reloads the open window. Auto-sync runs every 5 minutes when enabled.
  • Revoking access is one click (Disconnect), which also revokes the token at Google.

Important

Reconciliation is snapshot-level, not per-note. If you edit on two machines while both are offline, the machine that syncs second wins for the whole database — concurrent edits are not merged. Sync is designed as a reliable backup and a good hand-off between devices you use one at a time, not as multi-writer collaboration.

Note

Only the database is synced. Images live alongside it in attachments/ and are not uploaded, so a note pulled onto a second machine will show its text but not its pictures.

Where your data lives

Platform Path
macOS ~/Library/Application Support/monki-notes/
Windows %APPDATA%\monki-notes\
Linux ~/.config/monki-notes/

That folder holds monki-notes.db — an ordinary SQLite file you can open with any SQLite client — and an attachments/ directory of images. Settings → Show database file reveals it in your file manager.

Architecture

src/
├── main/          Electron main process (Node)
│   ├── index.ts       window creation, lifecycle, single-instance lock
│   ├── db.ts          SQLite schema, tree queries, FTS5 index
│   ├── attachments.ts image storage + the privileged monki:// scheme
│   ├── drive.ts       Google OAuth + Drive REST, no SDK dependency
│   ├── sync.ts        reconciliation, auto-sync timer, status broadcast
│   ├── ipc.ts         the whole main↔renderer contract
│   └── menu.ts        native application menu
├── preload/       contextBridge surface — the only API the UI can reach
├── renderer/      React UI (column browser, rich editor, search, settings)
└── shared/        dependency-free types used by all three

Security posture. nodeIntegration is off and contextIsolation is on; the renderer's entire capability set is the explicit allowlist in src/preload/index.ts. A CSP forbids remote code and remote images. Note bodies are HTML, so they pass through a whitelist sanitiser on load and on paste — unknown elements are unwrapped rather than dropped, javascript: URLs are stripped, and an <img> may only point at an attachment or a data: image. External links are handed to the system browser rather than opened in-app, and the app is a single instance so one process owns the database.

Data model. Folders and notes are rows in one nodes table with a self-referencing parent_id. Depth is therefore unbounded and free: paths, subtree deletion, and cycle checks are recursive CTEs rather than application loops. Ordering uses a sparse REAL position so a reorder is a single row update instead of a renumbering pass. A plain column mirrors the HTML as text purely so FTS5 indexes words instead of tags.

Development

npm run dev        # development app with HMR
npm run typecheck  # tsc over main, preload and renderer
npm run build      # typecheck + production bundle into out/
npm run dist       # installers for the current platform, into release/
npm run dist:mac   # or :win / :linux
npm run icons      # regenerate icon.icns / icon.ico from build/icon.png (macOS only)

Cross-platform installers are best produced on their own platform. better-sqlite3 is native, so electron-builder rebuilds it per target; on Windows/Linux it can't be built from a Mac without a container. Pushing a v* tag runs the release workflow, which builds all three platforms and attaches the installers to the GitHub release.

Tip

npm run dist:mac also builds the Intel target, which leaves better-sqlite3 compiled for x64 and makes npm run dev fail with an "incompatible architecture" error on Apple silicon. Run npm run postinstall to rebuild it for your own machine.

Signing

Unsigned builds work everywhere but need the quarantine workaround above on macOS. To sign, set the standard electron-builder environment variables before npm run dist:

  • macOS — CSC_LINK, CSC_KEY_PASSWORD, plus APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID for notarisation. Hardened runtime, entitlements and notarize: true are already configured; signing requires a paid Apple Developer Program membership.
  • Windows — CSC_LINK and CSC_KEY_PASSWORD.

Releases sign themselves once these repository secrets exist — MAC_CSC_LINK, MAC_CSC_KEY_PASSWORD, APPLE_ID, APPLE_APP_SPECIFIC_PASSWORD, APPLE_TEAM_ID. Without them the workflow keeps producing unsigned artifacts.

How it compares

MonkiNotes is not trying to replace a knowledge base or a team wiki. It is aimed at people who want a fast local notes app with real folders and nothing else attached.

MonkiNotes Typical cloud notes app
Account required No Usually yes
Works fully offline Yes, always Partially
Where notes live One SQLite file you own Vendor's servers
Folder nesting Unlimited, column browser Often 2–3 levels
Sync Optional, your own Google credentials Mandatory, vendor-run
Telemetry None Common
Price Free, MIT licensed Free tier + subscription

FAQ

Is MonkiNotes free? Yes — free and open source under the MIT licence, for personal and commercial use.

Does it work offline? Always. Everything is local by default; sync is an optional extra you switch on yourself.

Where are my notes stored? In a single SQLite database in your user data folder (see Where your data lives). You can open it with any SQLite client, back it up, or copy it to another machine.

Do I need a Google account? No. Google Drive sync is entirely optional and off by default.

Can I nest folders more than a few levels deep? Yes — there is no depth limit. The column browser shows five columns at a time and slides as you go deeper, so a ten-level hierarchy stays readable.

Does it support Markdown? The editor is rich text (WYSIWYG) rather than Markdown, with a formatting toolbar. Notes export as HTML.

Which platforms are supported? macOS (Apple silicon and Intel), Windows, and Linux (AppImage, deb, rpm).

Is it a Notion / Evernote / Apple Notes replacement? Only if what you want from them is fast local notes in deep folders. There are no databases, backlinks, collaboration, or web clipper.

Contributing

Issues and pull requests are welcome. Please run npm run typecheck before opening a PR, and keep the dependency list short — staying lightweight is the point of this project.

License

MIT


Built with Electron, React and SQLite.

About

Super lightweight, native-feeling note taking app for macOS, Windows & Linux — Finder-style column browser with unlimited folder depth, rich text notes, offline-first SQLite storage and optional Google Drive sync. No account, no server, no telemetry.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages