oximemo
Capture a thought before it's gone.
A fast, minimal, card-based memo app for macOS (Apple Silicon).
Where a human hits Option twice and a coding agent reads the same vault over a CLI — with parity, no cloud, and plain-text files as the source of truth.
oximemo is optimized for the speed of catching a thought. Every memo is a card; cards live on a grid. There is no AI summary, no auto-tagging, no chatbot — those trade away the capture speed and reliability this project exists to protect.
Two core scenarios, one vault:
- A human double-taps
Optionanywhere on macOS, types one line, and disappears back into their work. - An agent (coding agent, local script) reads and writes those same notes over the
oximemoCLI — safely, with no duplicates.
Highlights
- Files are the source of truth. Notes are plain
.mdfiles with TOML frontmatter.grepandcatwork. The index is just a cache — rebuildable at any time withoximemo reindex. - Three-tier storage, pure Rust. Plain files + a
redbmetadata index + atantivyBM25 full-text index. No SQLite, no C dependencies in the index layer. - Capture that doesn't make you wait. The overlay window is warmed up off-screen so it appears in a single frame (target ≤ 16 ms) on trigger.
- Human/agent parity. Every GUI operation is a CLI operation. Agent-facing commands default to JSON / NDJSON for clean streaming and scripting.
- Hash-based sync.
oximemo exportemits a body-less manifest of{id, hash, updated_at, deleted}; diff the hashes, fetch only what changed, advance your cursor. HandlesARG_MAXwith--ids-file/--ids-stdin. - OKLCH colors. Perceptually uniform, CSS-native color labels that look right in both light and dark mode.
- Hardened against external writes. The file watcher debounces, retries partial writes (editors, iCloud), and never crashes the indexer.
Table of contents
- System requirements
- Install
- Quick start (CLI)
- The vault
- Architecture
- Project structure
- Synchronization for agents
- Development
- Roadmap
- Contributing
- License
System requirements
- macOS 14+ on Apple Silicon (
aarch64-apple-darwin). - Rust 1.89+ (edition 2024) to build from source.
Windows, Linux, and mobile are intentionally out of scope for the MVP. See the design doc.
Install
From a release
Download the prebuilt oximemo binary and .dmg from the
latest release, then:
From source
# binary: target/release/oximemo
A Homebrew tap (
brew install) is planned. For now, use a release tarball or build from source.
Quick start (CLI)
The CLI is the authoritative interface — the same oximemo-core the desktop app uses.
# Capture a thought (text arg, or omit to read stdin)
# List recent notes — table for humans (default), JSON/NDJSON for agents
# Read one memo (JSON by default; --md for the raw file)
# Full-text search (BM25 over body + tags)
# Edit a memo (favorite / category / body) and manage categories
# Where does my vault live?
|
Global: --vault <PATH> (or OXIMEMO_VAULT) selects a non-default vault. Output formats: table (human), json (single array), ndjson (one value per line, the default for export/search). Timestamps are RFC 3339.
- Capture overlay: double-tap
Option(needs Accessibility / Input Monitoring permission), or the always-availableCmd+Shift+N, or the menu-bar icon.Entersaves & dismisses,Shift+Enternewline,Esccancels. - Card grid: search, tag/favorite filters, OKLCH color labels, virtualized for large vaults.
- Light/dark follows the macOS system appearance.
The vault
Notes are plain text — humans and agents can read them with anything.
vault/
├── memos/
│ └── 2026/07/
│ ├── 01991a2e-7c3f-7c91-9f3e-6b1a2e8f9c10.md
│ └── 01991a31-9b10-70aa-8c2e-4f0a1d2b3c44.md
├── .trash/ # soft-deleted memos
└── config.toml # optional vault settings
Each memo is one file with TOML frontmatter delimited by +++:
+++
id = "01991a2e-7c3f-7c91-9f3e-6b1a2e8f9c10"
created_at = "2026-07-28T10:15:03+09:00"
updated_at = "2026-07-28T10:15:03+09:00"
hash = "b3:6f2a9e1d4c7b8a90f1e2d3c4b5a6978…"
favorite = false
category = "inbox"
tags = ["idea", "oximemo"]
+++
The capture overlay must appear in under one frame.
The id is a time-sortable UUIDv7; the hash is b3: + BLAKE3 over the normalized body, tags, favorite flag, and category — so a pure metadata edit (add a tag, change a category) bumps the hash and is detected by sync. Full parsing rules and the safe-writing guide are in doc/DESIGN.md §5 and skills/oximemo/SKILL.md.
Architecture
oximemo-core is a pure-Rust library that owns the file store, indexes, file-watching, and sync. The desktop app (Tauri) and the CLI are thin adapters over oximemo_core::Vault — so the GUI and CLI always behave identically and can share one live vault (guarded by an fs2 advisory lock).
flowchart TB
subgraph Native["macOS native"]
CAP["oximemo-capture\nobjc2 global flagsChanged monitor\n(Option double-tap)"]
MENU["Menu-bar NSStatusItem"]
end
subgraph App["Tauri desktop app (apps/desktop)"]
RUST["Tauri Rust backend"]
UI["React 19 frontend\ncard grid + overlay"]
end
subgraph CLI["oximemo-cli"]
BIN["clap subcommands\nnew / list / search / export …"]
end
subgraph Core["oximemo-core (pure Rust)"]
FILES[("Files (*.md)\nsource of truth")]
LOCK["fs2 advisory lock"]
REDB[("redb metadata\nindex")]
TANT[("tantivy\nBM25 search")]
WATCH["notify watcher"]
SYNC["hash dedup / export"]
end
AGENT["External agent\n(coding agent / script)"]
CAP --> RUST
MENU --> RUST
RUST <--> UI
RUST --> Core
BIN --> Core
FILES --> WATCH --> REDB
WATCH --> TANT
LOCK -. guards .-> REDB
REDB --> SYNC
AGENT -- "CLI call" --> BIN
| Layer | Role | Tech |
|---|---|---|
| Source of truth | Human-readable memo bodies | .md files + TOML frontmatter |
| Metadata index | Fast pagination, filters, sync cursor | redb |
| Full-text index | BM25 keyword search | tantivy |
The index layers are 100% derivable from the files — corrupt or stale? One oximemo reindex restores them.
Project structure
oximemo/
├── crates/
│ ├── oximemo-core/ # Pure-Rust core: store, index, search, watcher, sync
│ ├── oximemo-cli/ # `oximemo` binary — clap adapter over oximemo-core
│ └── oximemo-capture/ # macOS global Option double-tap monitor (objc2)
├── apps/desktop/ # Tauri 2 + React 19 desktop app
│ ├── src-tauri/ # Rust backend
│ └── src/ # React frontend (Tailwind v4, Base UI, TanStack)
├── skills/oximemo/ # SKILL.md — agent-facing CLI guide
└── doc/DESIGN.md # Full design document
Synchronization for agents
The manifest is cheap on purpose — bodies are omitted, so it stays light for tens of thousands of notes.
- Fetch the manifest since your cursor:
- Diff against your local
id → hashcache (in your code):idunseen → fetchhashdiffers → fetch (covers tag/favorite/color edits too)deleted: true→ drop
- Fetch changed bodies in bulk (use
--ids-file/--ids-stdinpastARG_MAX): - Advance your cursor to the max
updated_atseen. Repeat.
The full procedure, output schemas, and the safe direct-write rules are in skills/oximemo/SKILL.md.
Development
# Rust
# Desktop frontend
A scratch vault is handy for manual testing:
See CONTRIBUTING.md for the full workflow, and doc/DESIGN.md for the design authority.
Roadmap
- v0.3+ — MCP server mode (
oximemo mcp serve), multiple vaults, iCloud-Drive vault auto-detection, optional wikilinks/backlinks. - Deferred by design — AI summaries, auto-tagging, chatbot, and embedding-based semantic search. BM25 keeps the capture loop fast; an offline embedding path (Rust
candle, Metal-accelerated) stays a possibility if real demand appears.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md first.
By contributing, you agree your contributions will be licensed under the MIT License.
License
Licensed under the MIT License.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you shall be licensed under the MIT License, without any additional terms or conditions.