Local models · Powered by Ollama

Local AI,
right on your desktop.

Ekorbia is a native Integrated Productivity Environment (IPE) for local models — your conversations, prompts, and indexed files live entirely on your machine. No cloud. No API keys. No telemetry.

Ekorbia app — multi-tab chat with a streaming reply, prompt library on the left, citation chips beneath the answer, and a Watches activity feed on the right
Chat, attachments with citations, watches, and a prompt library — all running locally on macOS.
01 / on-device

Your files stay home.

Embeddings run on CPU, in milliseconds, with nomic-embed-text. Index your notes, your journal, your ~/Documents — nothing leaves your laptop.

02 / native speed

Built in Rust & Tauri.

Streams responses with a stop button. SQLite + FTS5 underneath. Sub-millisecond cold-start of the overlay. Cold-warming-loaded model state visible in the status bar.

03 / yours forever

Plain markdown prompts.

Prompts are .md files with YAML frontmatter on your disk. Git-friendly. Shareable. Editable in any editor — no proprietary database to hold them hostage.

For the local-AI obsessed

Three things you get from staying local.

Your data never leaves your machine

Every chat, every embedding, every saved file lives in ~/Library/Application Support/ and nowhere else. The only network calls Ekorbia makes are to your local localhost:11434 Ollama daemon and the URLs you ask Watch to poll.

No telemetry, no analytics, no accounts

There's no sign-up, no API key, no usage tracking, no crash reporter phoning home. The app doesn't even know your name. Download the .dmg, install, run — that's the entire onboarding.

A memory file the model can read but never write

Ekorbia injects a markdown file of your choosing as system context on every send — facts about you, project conventions, writing style. The write_file tool is sandboxed away from it. The memory is yours to evolve; the model only sees it.

Need to disappear entirely? Start a private chat — nothing touches disk at all.

Prompt library

A library of prompts that live as files.

Every prompt is a markdown file with YAML frontmatter in your configured folder — git-friendly, shareable, editable in any editor. Five colored favorites for personal buckets, flat tag filters, full-text search across name, body, and tags. Type / in the composer to invoke one inline.

28 built-ins ship with the app, including Album Deep Dive, Brainstorm, Cliff Notes, Cover Letter Writer, Devil's Advocate, Lateral Thinking Puzzles, Log Triage, Murder Mystery Interrogation, Notes Synthesizer, Resume Coach, Sensitive Doc Q&A, Text Adventure, Tone Reframer, Translate (ES/FR/DE), and more.

Composer · type / to invoke

/research

Album Deep Dive
Brainstorm
Cliff Notes
Devil's Advocate
Notes Synthesizer
Resume Coach

↑↓ navigate  ·  ↩ insert  ·  esc close

Quick-query overlay

Press ⌘⇧Space. Ask anything. Never lose focus.

A transparent spotlight-style panel that pops up over any app and quietly answers — without stealing focus from your editor, your terminal, or your browser. Inline model picker, prompt picker, and streaming responses. Auto-hides on blur or esc.

Keeps its own model preference, so you can run a heavy reasoning model in the main window and a tiny fast one in the overlay. Click Send to main to escalate any overlay exchange into a full multi-turn chat in the main window.

explain CRDTs in plain english
⌥ gemma3:4b / explain-simply ↩ send · ⎋ close

Transparent vibrancy window · ~5ms cold-start · never steals focus

Private chats

Click the lock. Leaves no trace.

Click the lock icon beside New chat in the sidebar to open an ephemeral session. Messages, attachments, file saves — none of it touches the SQLite database. The conversation lives only in memory and disappears when you close the tab.

The composer hides the paperclip and folder buttons (attachments would persist to disk), the export kebab is hidden (nothing on disk to export from), and a lock glyph appears on the tab and as a banner above the composer so you're never visually confused about which mode you're in.

Tab strip · private chat
Q4 planning 📎 3
🔒 Private chat
Resume review
🔒 Private chat — nothing in this tab will be saved to disk.

Switching tabs preserves it in memory; closing the tab erases it.

Compare models

Two or three models. One prompt.

Click the columns button in the sidebar, pick 2 or 3 installed models, and the chat splits into adjacent columns. Send one prompt — every model streams its response in parallel, so you can watch them think side-by-side instead of swapping tabs to re-run the same question.

When one answer is clearly better, click Keep this beneath it. The losing columns collapse, the chat transitions back to a normal single-model conversation with the kept model, and the next message goes only to it — no wasted tokens, no cluttered history.

Comparison chat · 2 models
You Explain monads in one paragraph.
llama3:8b ▌ streaming

A monad is a design pattern for chaining computations that each return a wrapped value, letting you compose side-effects without unwrapping them by hand…

gemma2:9b ✓ done

Think of a monad as a burrito for values: it wraps a thing in context, and gives you one operator (>>=) to feed that thing through the next step without ever unwrapping.

Click Keep this and the chat continues with gemma2:9b alone.

Screenshot → chat

Press ⌘⇧1. Drag a region. Ask.

Hit the screenshot hotkey from any app — Ekorbia invokes macOS's native region selector (the same crosshair you already know from ⌘⇧4). Drag a region, press Space for window mode, or esc to cancel.

The captured PNG opens in a fresh chat tab with the image already attached as a vision attachment. If your current model can't see images, Ekorbia auto-switches to one that can — and tells you which one via a toast.

New chat · screenshot.png
🖼
Screenshot · 2486 × 1428
/var/folders/T/scr-202611.png
VISION

What's wrong with this chart?

The y-axis isn't zero-based, which visually exaggerates the trend. The gridlines are also missing a unit label…
✓ Switched to vision model: gemma3:4b
Watch

Ambient background work, while you sleep.

Point Ekorbia at a folder, an RSS feed, or any public URL. It polls on its own cadence, summarises only what's changed, and appends each summary to a notes file you can chat with later. Diff-mode URL watches send only the added/removed lines to the model — ideal for changelogs and release notes.

Optional native OS notifications (Notification Center on macOS) — coalesced per poll cycle, so five new files become one banner, not five.

Watches · activity feed
🌐 example.com / changelog "v0.7 adds nested transactions and a new diff mode…" 2m
📡 Hacker News 🔔 "Show HN: a new local-first sync engine for…" 14m
📁 ~/Inbox/ "New PDF: Q4-results.pdf — 8 sections summarised" 23m
🌐 status.cloudflare.com "Resolved: increased error rates in IAD region" 1h

Diff mode payload

  ## Added + Support for nested transactions + New `--diff` flag on the watch CLI - Deprecated: `legacy_mode` config key

Real use-cases · all 6 ship as built-in prompts

🌐

Release-notes diffs

Watch a project's CHANGELOG and get a diff-only summary every time a new version ships.

🌐

Rental / listing watcher

Poll a Craigslist or marketplace results page; get pinged the moment new listings appear.

📡

Research paper tracker

Subscribe to an arXiv RSS feed; abstracts summarised into a notes file, with link-follow on short feeds.

🌐

Wikipedia edit watcher

Tail an article's revision history; get notified when contested edits land.

🌐

Cloudflare / GCP uptime

Status pages summarised on every change — incident headlines, resolution timestamps, affected regions.

🌐

Price / availability watcher

CSS selector narrows to the price element; pings you when the number drops or an item comes back in stock.

Files & folders

Attach a folder. Ask a question. Get cited answers.

Attach .md, .txt, .pdf files, images, or whole directory trees. Small files are inlined verbatim; large ones are chunked, embedded locally with nomic-embed-text, and the top-6 most relevant chunks per query are retrieved at send time.

Replies come back with inline [N] citations that map to a Sources footer of clickable chips. Folder chips expand to show which sub-files matched and their relevance scores. Shift-click any chip to reveal in Finder. Re-indexing is incremental — change one file in a 500-file folder, click ↻, only that file re-embeds.

Assistant reply · Sources footer

The chunker preserves paragraph boundaries with a 100-char overlap [1], and embeddings are stored as packed f32 blobs for brute-force cosine retrieval [2]. The folder walker skips .git, node_modules, target by default [3].

Sources · click to reveal

[1] chunker.rs [2] attachments/types.rs [3] walker.rs 📁 src-tauri/ · 18 files
📁 src-tauri/   (expanded)
├── chunker.rs   0.87
├── attachments/types.rs   0.81
├── walker.rs   0.74
File generation · TOOL badge

Let the model write files, safely.

Tool-capable models (gemma3, llama 3.1+, qwen 2.5+, …) can call write_file during a chat to save any output — HTML, CSS, Python, configs, scripts — directly to a per-chat output directory you choose. First save asks permission; the choice sticks per chat.

Every write goes through a server-side sandbox that rejects .., absolute paths, NUL bytes, and symlink escapes — with unit tests for every rejection path. Writes are atomic (temp + rename), so a crash mid-write leaves the previous version intact.

Models without tool support get per-fenced-block Save buttons instead — same sandbox, same flow.

Files panel · per-chat output dir
~/.../Outputs/site-redesign/ Change… Reveal
index.html 2.1 KB · v3 5m ago
styles.css 847 B · v2 5m ago
build.sh 312 B 11m ago
gemma3:4b TOOL

badge appears on the model picker when the active model supports tool use

Memory file

One markdown file. Every chat.

A single markdown file Ekorbia injects as system context on every chat send. Useful for habitual context you'd otherwise re-type — facts about you, project conventions, writing style, things the model needs to know but you shouldn't have to repeat.

Read-only from the model's perspective — the write_file tool can't touch it. The memory is your shared context with the model, not something it gets to rewrite on its own. Edit it in any text editor, any time.

~/Documents/Ekorbia/memory.md
# About me

I'm a backend engineer working primarily in Rust
and Python. I prefer concise code review feedback
— call out problems without restating the patch.

# Writing style

- Active voice, present tense
- No marketing fluff ("seamlessly", "powerful")
- Em-dashes for asides, not parentheses

# Projects

- ekorbia — a local-AI desktop app (Tauri + React)
- forager — RSS reader I'm rewriting in Rust

3.4 KB · soft cap warns over 10 KB
Polished chat UX

Streaming, edit-retry, export, status.

Replies stream as they're generated; a Stop button freezes what's been written so far and marks the partial reply as Stopped so you see exactly where you cut it off. Click the pencil on any past user message to edit and resend; click retry on the last assistant reply to regenerate.

Export any chat to Markdown (clean role-tagged sections) or JSON (full row preservation with tool calls and timestamps). And the status bar distinguishes Ollama not running, model not pulled, cold, warming, loaded — no more wondering why the first token took 8 seconds.

Status bar · model state ladder

Cold start

gemma3:4b · cold

Warming up

gemma3:4b · warming

Ready

gemma3:4b · loaded

Indexing in the background

Indexing docs/ — 42/87

The same status bar shows a Stop button while a reply is mid-stream.

Themes

Five themes. Pick your weather.

One Dark and One Light for the editor-theme crowd. Ayu Dark, Ayu Mirage, and Ayu Light for the warmer palette folks. Switch in Settings — every panel, chip, badge, modal, and syntax-highlighted code block follows.

One Dark
One Light
Ayu Dark
Ayu Mirage
Ayu Light

Background · accent · link · keyword

Common questions

Things people ask.

Is Ekorbia free?

Yes. Ekorbia is free, open-source under the MIT license, with no subscription, no API key, no usage tracking, and no telemetry. Download the .dmg from the Releases page and you're done.

Does Ekorbia work offline?

Yes — once Ollama is installed and you've pulled at least one model, Ekorbia runs entirely offline. The only network calls it makes are to your local Ollama daemon on localhost:11434, and to the URLs you explicitly add to Watch. There's no cloud component.

Does my data leave my computer?

No. All conversations, attachments, embeddings, prompts, and saved files live in your local Application Support directory and in your chosen prompts folder. Ekorbia has no analytics, no crash reporter, no accounts, and no servers. The full source is on GitHub if you want to verify.

Which Ollama models work with Ekorbia?

Any model Ollama can run. The model picker lists everything you've pulled. For chat, llama3.2:3b is a fast starting point; for vision (attached images), gemma3:4b or llava work well; for the folder-RAG embeddings, nomic-embed-text is the default.

Tool-capable models (gemma3, llama 3.1+, qwen 2.5+) get a TOOL badge in the picker and can write files to disk.

Why is the .dmg unsigned?

Apple Developer ID is required for signing and the project doesn't currently carry that membership. The trade-off: macOS Gatekeeper shows a warning on first launch (or refuses outright with a "damaged" message — the README has a one-line xattr fix).

If you'd rather not run unsigned binaries, you can build from source instead: cargo tauri build produces a locally ad-hoc-signed binary that Gatekeeper accepts.

Does Ekorbia work on Windows or Linux?

Not yet officially. The codebase has Linux and Windows code paths (notifications use libnotify and WinToast respectively, the build targets are configured), but no packaged release ships for those platforms and the maintainers don't run them. PRs to harden the cross-platform paths are welcome.

Didn't find your answer?