Your notes, as files you own. A native macOS notes app: one folder per note, markdown inside, no database and no account.
Built with SwiftUI and AppKit. Rich text editing, on-device semantic search, live dictation, drawing, and a one-way bridge into an Obsidian vault.
Interface language: Polish and English, switchable at runtime.
Most notes apps put your writing in an opaque database and ask you to trust a sync service. NoteM stores every note as a folder on disk:
~/Documents/NoteM/
├── Praca/
│ └── 2026-07-31_10-14-22/
│ ├── note.md ← plain markdown, readable by anything
│ ├── note.rich ← full-fidelity formatting (colours, fonts, images)
│ ├── meta.json ← title, tags, dates, links
│ └── attachments/ ← images and files you dropped in
├── .trash/ ← soft-deleted notes, auto-purged after N days
└── .history/ ← up to 20 snapshots per note
Delete the app and your notes are still there, in a format you can read with
cat, grep through, back up, or open in any markdown editor.
- Rich text editor — WYSIWYG on top of markdown. Headings, bold/italic, checklists, ordered and unordered lists, inline code, colours and fonts.
- Two storage formats, one note.
note.mdkeeps the text portable for tools and scripts;note.richpreserves everything the markdown can't express (colours, pasted formatting, inline images) and is what the editor displays. - Paste sanitizer — Paste and Match Style (⌥⇧⌘V, also in the right-click menu) keeps the structure worth keeping — bold, italic, headings, lists, links — and drops the source's own fonts, sizes, colours and backgrounds. Plain ⌘V still pastes everything exactly as copied.
- Drawing canvas — sketch inside a note; the drawing lands as an attachment.
- Live dictation — click the mic and the recognized text appears in the note
as you speak. Fully on-device (
SpeechTranscriber, falling back toSFSpeechRecognizer), no audio file is written, and Polish is supported. - Spell checking and autocorrect — follows the interface language.
- Black or white note background, remembered across notes and launches.
- Autosave one second after you stop typing, with the previous version kept as a history snapshot.
- Categories are just folders. A note's category is the folder it sits in — visible in Finder, not an abstraction.
- Filing rules — "a note containing invoice goes to
Finance/{date}". First matching rule wins; drag to reorder. Only unfiled notes are moved, so editing an already-filed note never makes it hop folders. - Tags with autocomplete from tags already in use.
- Wiki links — type
[[Another note]]to link notes together. Each note shows its backlinks ("what links here") under the editor. - Smart folders — saved queries. Two built in (Today, Pinned), and you can define your own from conditions.
- Pinning keeps notes at the top of the list.
- Task lists — flag a note as a task list and it appears in the Tasks view with a badge counting what's still open.
- Cover colours per category, from a ten-theme palette.
- Exact search across titles, tags and note bodies.
- Semantic search — switch the toggle to By meaning and NoteM finds notes
about the same thing even when they don't contain your words. Runs on-device
via
NLContextualEmbedding(Apple's multilingual model, so Polish works too). Vectors are cached and recomputed only for notes whose content changed. - Command palette (⌘K) — jump to any note by fuzzy title match, or run any command without touching the menu bar.
- Quick capture — a hot corner of the screen or ⌥⌘N opens a floating capture panel from anywhere, without bringing the main window forward. New notes made this way still go through the normal filing rules.
- Attachments view — every image, file and web link across all notes in one list.
- iCloud Drive sync — notes live in your iCloud Drive as an ordinary folder. Changes made on another Mac are detected within about seven seconds.
- Conflict resolver — when the same note was edited on two Macs offline, both versions are shown side by side and you choose which to keep. Nothing is silently discarded.
- Unsaved work is protected — an incoming sync reload is deferred while the editor still holds text that hasn't reached the disk.
- Trash with a configurable retention window, restoring to the original folder.
- Version history — up to 20 snapshots of every note.
- Failed writes are reported. If a save doesn't reach the disk, the app says so instead of showing you a note it didn't store.
- Obsidian bridge — mirrors notes into an Obsidian vault as plain
.mdfiles with YAML front matter, attachments included and links rewritten to Obsidian's embed syntax. Strictly one-way: NoteM overwrites only files it created itself (identified by anotem-idin the front matter) and never touches a note you wrote in Obsidian. Trashing a note removes its copy from the vault. Restoring it brings the copy back when automatic mirroring is on; with manual sending the copy stays gone and the note is marked as not sent, so the marker never claims a file that isn't there. - HTML — a single self-contained page with images inlined as data URIs.
- PDF and print, with proper margins and pagination.
- Polish and English, switched at runtime without a restart.
- Ten accent themes.
- Three layouts for the start page: sections, columns, or macOS-style stacks.
NoteM makes no network connections. There is no telemetry, no analytics, no account and no server. Dictation and semantic search both run on-device. Your notes go to your disk and — only if you turn sync on — to your own iCloud Drive.
That includes pasting. The system's HTML reader fetches images and stylesheets a copied web fragment points at, so NoteM strips those references before the paste is read: nothing is requested, and no server learns that you pasted from its page. The cost is that an HTML-only paste arrives without pictures it referenced by URL — images copied from a browser come through the richer clipboard formats and are unaffected.
- macOS 26 or later
- Xcode 26 or later to build
Live dictation uses the newer SpeechTranscriber where the system provides it and
falls back to SFSpeechRecognizer otherwise, so it works across the supported
range. Semantic search quietly disables itself if the on-device embedding model
isn't available.
NoteM works without granting anything. Two optional features ask for a system permission the first time you turn them on, and both keep working — minus that feature — if you say no.
| Feature | Permission | If you decline |
|---|---|---|
| Live dictation | Microphone, Speech Recognition | Dictation won't start and says why; everything else is unaffected |
| Quick capture (⌥⌘N and the hot corner) | Accessibility | The shortcut and the corner stay silent. Quick Capture in Settings shows the current status and a button to System Settings |
Accessibility is what lets an app see keyboard events while another app is in front —
that's the only reason NoteM asks for it, and the handler ignores every key except
⌥⌘N (QuickCapture.swift). Keystrokes are neither recorded nor stored.
Deleting the app leaves your notes where they are — which is the point, but it is worth knowing what is still on disk afterwards:
| What | Where |
|---|---|
| Your notes | ~/Documents/NoteM/ — one folder per note, plus .trash/ and .history/ |
| The same notes, if sync was on | ~/Library/Mobile Documents/com~apple~CloudDocs/NoteM/ |
| Copies exported to Obsidian | inside your vault, wherever you pointed the bridge |
| Settings | ~/Library/Preferences/com.mikagosz.NoteM.plist |
| Accessibility / microphone grants | System Settings → Privacy & Security |
Nothing else is written anywhere. Removing the folders above removes every trace; none of it is needed by anything but NoteM.
git clone https://github.com/mikagosz/NoteM.git
cd NoteM
open NoteM.xcodeprojThen press ⌘R.
The project ships with a pinned local code-signing identity, which won't exist in your keychain. Set Signing & Capabilities → Signing Certificate to Sign to Run Locally, or point it at your own certificate.
Why a pinned certificate? macOS ties permissions such as Accessibility to an app's code signature. With the default ad-hoc signature that identity changes on every rebuild, so the system treats each build as a new app and asks for permission again, forever. Signing with a stable certificate — even a self-signed one you make yourself in Keychain Access — fixes it.
xcodebuild -project NoteM.xcodeproj -scheme NoteM -destination 'platform=macOS' testThe suite covers the storage layer, the Obsidian export, the filing engine and the save-on-quit path — the places where a bug costs you data rather than pixels.
| Area | Files |
|---|---|
| Storage | NoteStore.swift, Note.swift, NotesModel.swift |
| Editor | RichTextEditor.swift, MarkdownStyler.swift, EditorToolbar.swift, PasteSanitizer.swift |
| Views | ContentView.swift, NoteDetailView.swift |
| Organising | Categorization.swift, SmartFolder.swift, Attachment.swift, Thumbnails.swift |
| Search | SearchText.swift, SemanticIndex.swift, CommandPalette.swift |
| Input | VoiceNotes.swift, DrawingEditor.swift, QuickCapture.swift |
| Export | ObsidianExport.swift, HTMLExport.swift |
| Sync | Sync.swift |
| Shutdown | PendingWork.swift — flushes debounced writes when the app quits |
| Misc | Theme.swift, Localization.swift |
The source code is MIT — see LICENSE.
The artwork is not. The app icon (MyApp/notem.icon/), the in-app images
(MyApp/Assets.xcassets/ObsidianCrystal*) and the icon used above
(docs/assets/notem-icon.png) are Copyright (c) 2026 mikagosz, all rights reserved, and
are excluded from the MIT grant — see NOTICE. They ship with the repository so
the project builds and this page renders as it is shipped; if you fork this project,
replace them with your own.
