← writingApr 2026 · 2 min · CLI · Zig

ogai: local-first semantic search for your Downloads, in 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:

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.