# ogai: local-first semantic search for your Downloads, in Zig

> A tiny Zig tool that indexes your files, embeds snippets with Gemini, and answers queries from the CLI or a local HTTP API, and why Zig was the right call for it.

By Himanshu Maurya · 2026-04-20 · CLI · Zig · 2 min
Canonical: https://codingstark.com/blog/ogai-semantic-search-zig/

Your Downloads folder is a graveyard of things you meant to read. **ogai** is a local-first semantic index over it: it scans files, extracts searchable snippets, generates embeddings with Gemini, and lets you query from a CLI or a small local HTTP API.

### Three modules, one binary

- **Scanner** — walks the folder, extracts snippets per file type.
- **Vector index** — stores embeddings and does the nearest-neighbour search.
- **Server** — a tiny HTTP API so other tools (or an editor) can query it.

It's local-first by design: your files never leave the machine except the snippet you choose to embed. The index lives on disk, so search is instant on the second run.

### Why Zig

I wanted a single static binary with no runtime, predictable memory, and honest control over the file-walking and vector math. Zig gives you manual allocation without the papercuts, and `comptime` lets you specialise the distance function without a template soup:

```zig
fn cosine(a: []const f32, b: []const f32) f32 {
    var dot: f32 = 0; var na: f32 = 0; var nb: f32 = 0;
    for (a, b) |x, y| { dot += x * y; na += x * x; nb += y * y; }
    return dot / (@sqrt(na) * @sqrt(nb));
}
```

That's the whole ranking core. The interesting engineering is upstream — deciding *what* to embed — but Zig made the plumbing small, fast, and boring in the best way.
