Froots
Docs · Complete reference · 22 min read

Everything Froots does, on one page.

Froots is a local-first workspace that combines a rich markdown editor, a personal knowledge vault, sentence-compiled automations, and four always-on agents that can read, write, and act on your behalf. This page is the single source of truth — bookmark it, search it, skim the sidebar. Deeper guides are linked from each section.

Coming from another app?

Froots reads Obsidian and Bear vaults natively and imports from Notion, Apple Notes, Things, and Roam. Jump to importing →.

Install

Download the app, drag it, open it. No account required — a local vault is created the first time you launch. Froots is ~48 MB installed and runs offline by default.

macOS · Universal .dmg from downloads, or Homebrew. Signed & notarized.

# macOS
brew install froots/tap/froots

Windows · .exe or winget. Windows 10 22H2+, x64 and ARM64. EV-signed installer.

winget install Froots.Froots

Linux · AppImage works everywhere; native .deb and .rpm are on the downloads page.

curl -fsSL froots.app/install | sh

First run

On first launch, Froots asks three things and then gets out of your way:

1. Pick a global hotkey. Default is ⌘⇧Space on macOS, Ctrl⇧Space elsewhere. This pops Froots from anywhere, over anything. Changeable any time in Settings → General.

2. Review your agents. A small panel shows Lime, Yuzu, Clem, and Cherry — the four built-in agents. Each one reads from an editable IDENTITY.md, SOUL.md, and USER.md you can tweak later. Skip it and keep the defaults, or make them yours.

3. Pick where the vault lives. Default is ~/Froots. Any folder works — Dropbox, iCloud Drive, a USB stick. If the folder already contains a vault (ours, Obsidian, or Bear), Froots will adopt it.

No API keys required to start. Built-in agents use our managed routing; you can switch to your own OpenAI/Anthropic/Gemini key — or a local Ollama or LM Studio endpoint — in Settings → Models whenever you want.

The 60-second tour

The main window has three panes you'll learn by Tuesday:

Library (left). Your vault tree — folders, notes, saved routines, and agents. Drag to reorder; right-click to rename, move, or archive.

Editor (middle). The note you're on. Type a paragraph, press ⌘⇧R, get a routine. Press ⌘K for the block menu.

Agent (right). Whichever agent you're talking to. Collapses to a keycap with ⌘\; expands when you @-mention one.

Everything else — inbox, widgets, plugins, settings — lives behind the command palette (⌘K in chrome, ⌘⇧P everywhere). Search finds any note, routine, agent, setting, or command you've ever created.

Importing from other apps

Froots reads external formats natively — it will never fork your folder or "convert" files behind your back.

Blocks & the block menu

The editor is block-based but stored as plain markdown. Press ⌘K at the start of a line to open the block menu: headings, quotes, tables, code blocks, callouts, math, diagrams, tasks, dividers, embeds, and any plugin-supplied block. Type / anywhere to inline-search the same menu. Drag the six-dot handle to reorder.

Every block has an identity — meaning you can link to a single paragraph of a note with [[note#^block-id]]. Backlinks point to the block, not just the file.

Markdown cheatsheet

Standard CommonMark plus GFM and a handful of extensions. What you write is what lives on disk.

# Heading 1 / ## 2 / ### 3
**bold** *italic* ~~strike~~ ==highlight== ^sup^ ~sub~
> quote
- [ ] task   - [x] done   - normal list   1. numbered
`inline code`
```ts → fenced code with language
| table | | | → pipe tables
[[wikilink]]   [[note#heading]]   [[note#^block]]
![[image.png|300]]   ![[video.mp4]]   ![[audio.m4a]]
> [!note] Callout title   → GitHub-style admonitions
$$ inline math $$   $$ block math $$   ```mermaid → diagrams

Type [[ to autocomplete any note, block, or heading in the vault — including notes that don't exist yet (creating one is a keystroke). Rename a note and every link updates atomically; the link indexer is incremental and survives 10,000-note vaults without stutter.

Every note has a Linked mentions drawer at the bottom — what points here, what quotes here — plus Unlinked mentions that surface pages with the same title but no link yet. Click to wire them up.

Graph view

A force-directed graph of your vault — notes as nodes, links as edges, folders as faint clusters. Filter by tag, folder, date, or free-text query. Hover a node to peek the note; click to open; right-click to pin. The whole graph runs at 60 fps up to ~8,000 nodes.

The Local graph panel lives inside the editor and shows just the current note and its first- or second-degree neighbors. Useful while writing; less useful while procrastinating.

Code, math & diagrams

Syntax highlighting via Shiki — 150+ languages, shared VS Code themes. Math via KaTeX, both inline ($...$) and block ($$...$$). Diagrams via Mermaid — flowcharts, sequence, gantt, state, ERD, mindmaps — all rendered live as you type.

```mermaid
flowchart LR
  alarm --> brew[HomeKit: brew] --> shutters[Shutters: open]
```

Code blocks are executable where it's safe — SQL runs against the vault's built-in store, shell snippets prompt before executing, Python runs in a sandboxed environment if you have uv installed.

Tables & checklists

Tables are editable with Tab and Shift+Tab; drag columns to reorder. Under the hood they're CSV-compatible, so a 20-row note opens cleanly in Numbers or Excel.

Checklists understand a few small gestures: - [ ] for open, - [x] for done, - [/] for in progress, - [?] for question. Completed tasks fade; a query block (```tasks) aggregates open tasks from the whole vault by folder, tag, or date.

Where notes live

Your vault is a folder of plain .md files on your computer. That's it. Froots keeps no proprietary binary format, no cloud database, no lock-in. If Froots disappeared tomorrow, you'd still have every byte you ever wrote, readable by any text editor.

Default layout — everything is optional:

~/Froots/
├── Library/            # your notes
├── Routines/           # saved automations (*.routine.md)
├── Agents/             # agent identity files
│   ├── Lime.md
│   ├── Yuzu.md
│   ├── Clem.md
│   └── Cherry.md
├── Memory/             # what agents learned about you
│   ├── context.md
│   ├── decisions.md
│   └── learnings.md
├── .assets/            # images, video, attachments
└── .git/               # local history (optional)

Search is both full-text and semantic. Every note is chunked (~240 tokens, 40-token overlap) and embedded locally with a 384-dim sentence model (bge-small-en-v1.5). The model is ~130 MB and bundled with the app — no data ever leaves your machine.

Type in the command palette and results are ranked by exact + lexical + vector similarity; a small dial lets you bias toward "literal" or "meaning." Agents use the same index when answering questions about your vault.

Local git history

Every save is auto-committed to a local git repo inside your vault. Nothing is pushed anywhere — it's purely a safety net. Library → Right click → History gives you a visual diff timeline, per note. Hit ⌘Z across a whole day, not just the last edit.

If you want remote backups, point git at any remote — GitHub, a self-hosted Gitea, a USB stick — and commits push on the same cadence as sync.

⌘⇧R — sentence to routine

Highlight a paragraph of plain English, press ⌘⇧R, and Froots compiles it into a runnable routine. The compiler parses triggers ("every weekday at 8am"), tools ("pull from Linear"), agents ("hand to Scribe"), and outputs ("write to Notion"), emits a graph, and lets you tweak it visually before saving.

Example

"Every weekday at 8am, pick the three ripest issues from Linear and bring them to my desk with context."

Cron (Mon–Fri, 08:00)Linear.query(priority:high, state:todo)Agent: Scribe (summarize top 3)Notion.write(db: Daily)Notify(me)

Routines are saved as .routine.md files — readable, diffable, committable. Share one with a teammate by sending the file.

Triggers

Five built-in trigger types cover almost every automation:

Cron — any natural-language schedule ("every Sunday at 9pm", "first weekday of the month"). Time zones are explicit; DST is handled.

Webhook — Froots exposes per-routine signed URLs; hit one and the routine runs.

Event — fired by plugins: calendar.event-about-to-start, inbox.message.received, vault.note.created, github.push, and ~90 others.

Manual — just "run it now", triggered from the editor, the agent pane, or a hotkey.

Chain — another routine's completion event — routines can fan in and out.

Branches & variables

Routines support if / else, parallel fan-out with all, first-past-the-post with race, and typed variables that flow between steps. Loops are bounded — infinite loops are a compile-time error. Every run produces a trace: an immutable log of every step's input, output, and timing, replayable from any point.

50+ integrations

Integrations ship as plugins and each is a thin wrapper around its vendor SDK. The current list — non-exhaustive, growing weekly:

Communication — iMessage (macOS), Gmail, IMAP/SMTP, Slack, Discord, Telegram, Signal, WhatsApp, X/Twitter DMs, Matrix, Resend, Loops.

Productivity — Notion, Linear, GitHub, GitLab, Jira, Asana, Things, Apple Reminders, Todoist, Trello, Calendar (Google / Apple / Outlook / CalDAV).

Home & devices — HomeKit, Home Assistant, Sonos, Spotify, Wyze, Alexa, Philips Hue.

Dev & infra — shell, Docker, Fly.io, Vercel, Cloudflare, Supabase, Postgres, SQLite, Redis, Stripe, Polar.

Content & creative — Figma, Canva, Blender, Rive, CapCut, Apple Notes, Bear, Obsidian, 1Password, PDF, OCR, local Whisper.

The four built-in agents

Every Froots workspace ships with four agents, each with a distinct prompt, toolset, and voice. Mention any of them with @ in the editor or the chat pane.

Write your own by dropping a markdown file into Agents/ — see Writing your own below.

Persistent memory

Agents have memory. When Clem learns that your company's QA staging runs on staging.acme.dev, she writes that to Memory/context.md. When Yuzu notices you hate the word "leverage," she adds it to Memory/learnings.md. Every memory file is plain markdown — you can read, edit, or delete any entry.

Memory is indexed with the same embedding model as the vault; agents retrieve relevant facts automatically, scored by recency × similarity. The Memory panel (⌘⇧M) shows what's currently in context, and lets you pin or forget items with one click.

Tool scoping & trust

Agents have three trust levels, set per-agent and per-workspace:

Careful. Default for new agents. Every tool call — read, write, shell, network — prompts you first. Noisy but safe. Good for agents you just downloaded.

Balanced. Reads are free. Writes, shell, and network calls prompt once per routine, then remember for the session. The right default for Lime, Yuzu, Cherry.

Yolo. No prompts. Good for Clem inside an isolated dev environment; bad for Clem on your laptop. Usually what you want on a dedicated automation machine.

Per-tool scoping — "this agent can read the vault but not the web" — lives in Settings → Agents → Tool Policy, stored as plain YAML you can version-control.

Bring your own model

Froots runs on any of these, mixed and matched per agent:

Managed — our default. Routes to the best model for the task, billed through your subscription. Zero config.

API keys — Anthropic, OpenAI, Google, Mistral, Groq, DeepSeek, xAI. Drop a key in Settings → Models and it's used immediately. Usage shows up in-app.

Local — Ollama, LM Studio, llama.cpp, mlx. Any OpenAI-compatible endpoint works. We bundle presets for Llama 3.3, Qwen 2.5, DeepSeek R1, and Phi-4.

Enterprise — Azure OpenAI, AWS Bedrock, Vertex. Managed IAM; per-agent model pinning; audit log export.

Per-agent: Lime might use a local 7B for searching, Yuzu Claude Opus for voice, Clem GPT-4.1 for code, Cherry a cheap Haiku for cleanup. Set it and forget it.

Writing your own

An agent is a markdown file in Agents/ with frontmatter:

---
name: Bruno
emoji: 🍌
role: "Reviews my code before anyone else sees it."
tools: [vault.read, vault.write, shell, github]
model: claude-4-sonnet
trust: balanced
---

# Identity
You are Bruno. You read diffs like a bored senior who doesn't want to
be rude but also doesn't want the team to ship slop...

That's it. Drop it in the folder and Bruno appears in the @-mention list, the chat pane, and the routine compiler on next launch. Share an agent by sending the file. Publish one to the community registry by adding publish: true.

Native widgets

Any agent can generate a native OS widget on demand. Ask Cherry for "a widget of my top three open threads" and a SwiftUI WidgetKit widget appears on macOS's Notification Center / lock screen; on Windows, it lands as an Adaptive Card on the Widget Board. On iOS and Android, same contract — a Lock-Screen / Always-On tile.

Widgets are declared in a tiny layout schema — vstack, hstack, text, gauge, action, image, spacer, divider — that compiles to native components per platform. You can hand-edit the JSON, or ask an agent to "make it smaller" or "add a progress bar." They update on their own cadence, from a minute to a day.

The unified inbox

The inbox is a single sortable view of messages across every channel you've connected — with one-row-per-thread, priority sorting, and per-thread agent summaries. Triage by keyboard: E archive, D delete, R reply, ⌘Enter "let Clem handle it."

Replying is native per channel: a Telegram reply goes out over the bot, a Slack reply hits the right channel with the right thread ID, an iMessage reply is sent via your actual iMessage identity on macOS. No webhook games, no proxy inbox.

Supported channels

Connect any of these in Settings → Inbox:

iMessage / SMS — macOS only; reads from ~/Library/Messages/chat.db and sends via AppleScript. Requires Full Disk Access.

Email — Gmail (OAuth), IMAP/SMTP (any provider), Outlook/Exchange.

Messaging — Slack (Socket Mode, no webhook), Discord, Telegram (bot or user), Signal (signal-cli), WhatsApp, Matrix.

Social — X/Twitter DMs, Bluesky DMs, Mastodon.

Each channel is a plugin — if you need a new one, it's ~150 lines of TypeScript.

Plugin library

Froots ships with ~60 built-in plugins — everything in Integrations plus a long tail: Blender, Canva, Rive, CapCut, Apple Shortcuts, 1Password, Stripe, Polar, Fly.io, PageSpeed, PDF, OCR, Whisper, and more. Each is on/off-able per agent and per-routine.

Community plugins install from a URL or the registry. All plugins run in a sandbox with no ambient filesystem or network access — they must declare capabilities in a manifest and you approve them on first use. Sandbox escapes aren't a thing; we use OS-level process isolation on every platform.

The plugin SDK

A plugin is a directory:

my-plugin/
├── manifest.json       # capabilities + metadata
├── index.ts            # actions, triggers, blocks
└── README.md

The SDK is TypeScript-first, with Zod schemas for every action's input/output. Hot reload while developing — changes to index.ts re-register immediately. Publish to the registry with froots plugin publish, or share a folder directly.

Sync

Sync is local-first: you always have a full working copy, even offline. Changes replay when you reconnect. The sync engine is a CRDT (Yjs under the hood) — concurrent edits merge cleanly, without "which version do you want" modals.

Sync is off by default. To turn it on: Settings → Sync → Pick a backend → Sign in. No data ever leaves your device before you explicitly choose a backend.

End-to-end encryption

When sync is on, your vault is end-to-end encrypted with a key derived from your passphrase. We cannot read your notes — not even to debug them. Lose the passphrase and your remote copy is gone; local copies still work. Keys can be rotated any time; old ciphertext is re-wrapped asynchronously in the background.

The cryptography is boring on purpose — XChaCha20-Poly1305 for content, Argon2id for the passphrase KDF, Ed25519 for signing — all via libsodium. Full spec: security.froots.ai.

Sync backends

Pick one. Move between them at any time — the sync protocol is backend-agnostic.

Froots Cloud — ours. Cloudflare Workers + R2 + D1. Zero setup, 99.99% uptime, included with Pro and Teams tiers.

Your cloud storage — iCloud Drive, Dropbox, Google Drive, OneDrive, Box. Point at a folder, we do the rest. Useful if your IT department already approves one.

S3-compatible — AWS S3, Cloudflare R2, Backblaze B2, MinIO, self-hosted. Good for teams with compliance requirements.

Git — push to any git remote. Best for devs who already have infrastructure; worst for large attachments.

Self-hosting

The sync server is a single open-source Rust binary under AGPL-3.0. Run it on a $5 VPS, in Docker, or on Fly.io / Railway with a one-click template. It uses SQLite + S3-compatible storage underneath — no Postgres required.

docker run -p 8080:8080 -v froots:/data ghcr.io/froots/sync:latest

Multi-user mode uses standard OIDC; a workspace admin can invite users, set quotas, and export audit logs. Teams tier includes a hosted control plane if you don't want to run one yourself.

Keyboard shortcuts

A partial list — everything is rebindable in Settings → Keyboard.

On-disk layout

Beyond your vault, Froots keeps a small amount of app data outside it:

# macOS
~/Library/Application Support/Froots/
  config.json             # hotkey, model prefs, trust levels
  keystore.db             # encrypted API keys (OS keychain-backed)
  models/                 # bundled embedding model + any local models
  cache/                  # incremental search index (rebuildable)
  logs/                   # last 30 days, ring-buffered

# Windows
%APPDATA%\Froots\           # same layout

# Linux
~/.config/froots/          # same layout (XDG-compliant)

Command-line

Froots ships a small CLI that talks to the running app over a local socket. Useful for scripting from shell, CI, or a cron job outside Froots.

froots note new "Meeting with K."
froots routine run daily-harvest
froots search "quarterly plan" --semantic
froots agent ask @clem "deploy staging"
froots sync --status
froots plugin install github:froots/plugin-tailscale

That's the full surface of the app, on one page. If something doesn't work like this document says, it's a bug — file it at github.com/froots/froots/issues.