Open source

Building vanilla: why our releases ship minimal

April 18, 2026 · 6 min read

We ship tools that are intentionally understated: minimal opinions, clear interfaces, everything exposed. The goal is not completeness out of the box. It is a base that teams can actually customize without rewriting. Here is what that principle looks like in practice.

Where the name comes from

"Vanilla" usually means plain, unmodified, the default version of something. We use it that way on purpose. A vanilla release is one that has not been flavored yet. It does not have opinions baked in that you did not ask for. It is the starting point, not the finished product.

This is a deliberate stance against a common pattern in developer tooling: the framework that tries to handle every case, the library that grows a plugin for every need, the platform that adds features until no one can understand the full surface area. These tools can be powerful, but they are hard to own. When something breaks, or when your use case does not quite fit the assumptions, you are fighting the framework instead of solving your problem.

We think the right infrastructure has a different shape: small, readable, understandable in full, and designed to be the starting point for your specific implementation.

What "vanilla" means as a design principle

A vanilla release has a few specific properties.

It does one thing. VanillaGraph ingests documents and produces a wikilink-connected knowledge graph. That is the job. It does not also manage your embeddings, host your vector index, provide an agent runtime, or make deployment decisions. Those are separate problems that deserve separate tools.

Its internals are exposed. Every meaningful decision in the pipeline is visible in the source. There are no magic methods, no opaque preprocessing steps, no behavior that you cannot trace by reading the code. If you want to understand what VanillaGraph does to your documents, you can read it in an afternoon.

It has clear interfaces. The inputs and outputs are defined, documented, and stable. You can swap the document parser, change the graph storage format, or replace the wikilink extraction logic without touching the rest of the system.

The goal is a base that teams can actually customize without rewriting. Not a framework. A starting point.

Why completeness is overrated

There is a version of VanillaGraph we could have built that handles PDF extraction, manages embedding models, provides a query API, ships with a web interface, and integrates with ten popular agent frameworks. It would have more features on day one. It would also be significantly harder to understand, harder to maintain, and much harder to adapt when your use case differs from what we assumed.

Most of the teams we want to help are building something specific. A code review agent with a particular memory structure. A document processing pipeline with unusual input formats. An operational intelligence system tuned to their trace data. A generic tool with many features is less useful to them than a focused tool that fits cleanly into their architecture.

The features we do not ship are not oversights. They are deliberate absences that leave room for your implementation.

Clear interfaces over rich ones

The test for a clean interface is whether you can describe it in one sentence. VanillaGraph's core interface is: give it a directory of documents, it produces a directory of wikilink-connected markdown files. You can point that at a vector store, a graph database, a search index, or anything else. The output format is intentionally boring for this reason.

Rich interfaces are seductive. It is tempting to add convenience methods, configuration knobs, and smart defaults that handle common cases automatically. Each addition makes the tool easier to use in the specific case the author imagined, and harder to adapt to every other case.

We add an interface when the alternative is unreasonable friction. We do not add one to make a demo look more complete.

What it looks like in VanillaGraph

The pipeline has three stages: reading source documents, building context from their content, and writing the graph to disk. Each stage is a separate module with a clear input and output. If you want to add a new document type, you modify the reader. If you want a different graph format, you modify the writer. The stages do not bleed into each other.

The wikilink format was chosen because it is readable, writable by hand, and compatible with existing tools like Obsidian and Roam. You can inspect the graph output with a text editor. You do not need a special viewer or query tool to understand what the pipeline produced. That legibility is part of the design.

The forking philosophy

Our releases are starting points. We expect teams to fork, extend, and replace pieces as their needs evolve. That is the intended use.

This means we are deliberate about what goes into the main project versus what should live in a fork. Features that are specific to one domain, one company's data structure, or one agent architecture do not belong in VanillaGraph core. They belong in your implementation, built on top of a foundation you can understand and trust.

Open source projects often resist this. There is social pressure to merge contributions, to grow the feature set, to become the most complete solution. We think the more valuable thing to be is the most understandable one. A tool you can read, trust, and adapt is more useful than a tool that tries to do everything and succeeds at none of it completely.

If you have built something on top of VanillaGraph that you think others would find useful, we want to hear about it. Share it in the Discord. Keep it your own. Fork the repo and make it yours.