Resin: a C# vector store with an append-only anything key/value layer
Language model search engine built on a vector database and an anything key/value store.
At a glance
- What is it?
- Resin is an MIT-licensed C# reboot of an older search engine project, built around a column-oriented key/value store and text analysis utilities. The storage semantics are documented in unusual detail; the language model and search engine parts are not.
- Who is it for?
- Adopt Resin if you are working in C#, want an on-disk column store with append-only value semantics and can read the source of the storage layer to confirm behaviour the README does not specify, such as page sizes and serialization triggers. Do not adopt it if you need a documented ranking pipeline or a stable public API today: the README describes a reboot, there are no retrieved releases, and the language model and search engine claims have no accompanying specification.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 95 days ago.
- What is it written in?
- Mainly C#, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem Resin addresses: strings, vectors and keys in one store
Most search stacks glue together three things that disagree about how data should be laid out: an inverted index for terms, a vector store for embeddings, and a plain key/value store for metadata. Resin's premise, as the README states it, is to be all three at once. It describes itself as a vector space search engine, a vector database and an anything key/value store, and says it can produce large language models out of strings and large anything models out of byte arrays. The target reader is a C# engineer who wants the storage primitives and the text analysis in the same process, without pulling in a JVM or a Python service. The README's highlights point at that audience directly: page and column readers and writers, text analysis utilities for strings, bags of words or chars and vectors, and commandline tools for building and validating lexicons. Nothing in the material describes a hosted service, a query language or a ranking model, so treat the project as a library and a set of commandline tools rather than a product.
Column semantics: keys are a set, values are a chain
The storage layer is where the README is most concrete, and the design is worth reading closely. A column holds each TKey at most once in its column-wide snapshot. Both TryPut and PutOrAppend enforce that, which the README says makes columns effectively sets of keys and enables union, intersection and joins across columns. TryPut inserts only if the key is absent from the snapshot, returns false if it is present, and triggers page serialization when the page fills. PutOrAppend is the more interesting call: if the key already exists anywhere in the column, no new key is stored, and instead the new value is linked onto the existing one through a fixed-size LinkedAddressNode written into the value stream. The README specifies tail-appending order, so the original value stays first and each appended value follows in insertion order, with the address entry pointing at the list head once linking is active. Reads reverse that. Get returns the concatenated bytes of all linked values, or an empty span when the key is missing. GetMany returns the same concatenation and reports the item count through an out parameter, with count = 1 for a single raw value and count = 0 for a missing key. This is a small API with a clear contract, and the contract is the reason to care about it.
Three files, one append-only rule
A column is persisted as three streams. The .key stream holds the sorted sequence of TKey representations per page and column, written in fixed-size slots (the README says sizeof(long) per entry for page-level storage) and serialized in page batches; the column-wide snapshot is built by reading and sorting this stream. The .adr stream holds Address structs aligned with the .key entries, each carrying an Offset and a Length. For a raw value, the address points straight into .val. For a linked value, it points at a LinkedAddressNode head in .val, and the node chain yields the multiple values for that key. The .val stream holds the value bytes and the node headers. The rule that ties it together is that .val is append-only: existing bytes are never modified in place, new values go at the end, and linking appends node headers rather than rewriting values. The README lists the benefits as stable offsets for caching addresses, linear scaling on append, and intact historical values. There is a practical consequence the README does not spell out: an append-heavy workload grows the value file without reclaiming space from superseded data, so compaction is a problem the application has to own unless the source does something the README omits.
TKey restrictions are the sharpest edge in the design
The README devotes a section to key restrictions, and it is the part most likely to bite. TKey must be a value type implementing both IEquatable<TKey> and IComparable<TKey>. Ordering and equality have to be stable across sessions, because the column-wide snapshot uses BinarySearch over sorted keys, which means CompareTo must define a strict total order consistent with Equals. Page-level storage operates on long keys. Double and float are stored through their IEEE bit representations, int and long go in directly, and any other TKey type is hashed via GetHashCode to a long for page-level operations. That last clause is the risk. The README states it plainly: collisions affect page-level operations since non-primitive keys are hashed to long. It recommends numeric primitives for deterministic ordering and lookup, and for custom structs asks for consistent Equals and CompareTo plus a stable, evenly distributed GetHashCode. If you are indexing string terms, this is the design decision to think about before anything else, because a hash collision at the page level is a correctness problem, not a performance one.
Getting it running: three namespaces and a CLI
The usage section is short and names three entry points rather than giving a full walkthrough. Resin.KeyValue is the on-disk structures and read/write sessions. Resin.TextAnalysis covers StringAnalyzer, VectorOperations and similarity tooling. Resin.WikipediaCommandLine holds the commandline tools for building and validating lexicons, and the README points to Resin.WikipediaCommandLine/README.md for detailed CLI usage and setup. There is no quickstart in the top-level README, no NuGet install line, no sample program and no configuration key reference, so the concrete commands live in that subdirectory README and in the source. The build is a C# solution, and the README describes the design as dependency light and easy to extend, which is consistent with a project where the interesting behaviour is in the storage code rather than in a framework. If you want to evaluate Resin, the honest path is to clone the repository, read Resin.WikipediaCommandLine/README.md, and run the commandline tools against a lexicon before writing any application code.
Where the README stops: the language model claim
The introduction says Resin can produce large language models out of strings and large anything models out of byte arrays. Nothing in the supplied README explains how. There is no description of training, of what a model looks like on disk, of how a query is scored, or of what the vector space model does at search time. The topics list includes information-retrieval, nlu-engine, search-algorithms and vector-space-model, which tells you the intended territory, but the material does not describe a mechanism. This matters for adoption decisions. The storage layer is specified well enough to reason about; the search and model layer is not. A reader comparing Resin against an established vector database will find no recall figures, no index type description and no latency claims here. The README itself frames the project as a reboot of an older Resin repository, which suggests the model side is being rebuilt rather than carried over intact. Treat the key/value and text analysis pieces as the part you can evaluate today.
Storage engine or search engine: picking the right comparison
The natural alternative depends on which half of Resin you want. If you want the on-disk column store with append-only values and linked multi-values, the closest comparison is a general embedded key/value store such as an LSM-tree engine, and the difference in approach is structural. An LSM store buffers writes in memory and merges sorted runs to disk, which gives write throughput and background compaction but means a key can live in several files at once and reads may consult more than one. Resin instead keeps a sorted key stream per page, an aligned address stream and a single append-only value stream, with multi-values expressed as node chains rather than as repeated keys. That design gives stable offsets and a cheap read path, and it puts the burden of reclaiming space on the caller. If what you actually want is vector similarity search, the comparison is a purpose-built vector index, which typically trades exactness for speed through approximate structures. Resin's README does not describe an approximate index, so there is no basis in this material to compare recall or throughput against one.
Maintenance, licensing and what to verify
The licence is MIT, which permits commercial use, modification and redistribution provided the copyright notice and permission notice are included; that is a summary of the licence family, not legal advice, and you should read the LICENSE file in the repository for the operative text. Maintenance signals in the supplied material are thin: no releases were retrieved, the last push is dated 2026-06-12, and the README describes the project as a reboot of an older repository, which usually means the public API is still moving. The contributing section asks for clear motivation, tests when applicable and concise changes, with no stated compatibility policy, no versioning scheme and no deprecation process. For an engineer deciding whether to build on Resin, the practical consequence is that you should pin to a specific commit rather than track the main branch, and you should expect to read the storage source when the README is silent on page sizes, serialization thresholds and compaction. Those three details determine whether the append-only value stream fits your write pattern or grows without bound.
Editorial conclusion
Adopt Resin if you are working in C#, want an on-disk column store with append-only value semantics and can read the source of the storage layer to confirm behaviour the README does not specify, such as page sizes and serialization triggers. Do not adopt it if you need a documented ranking pipeline or a stable public API today: the README describes a reboot, there are no retrieved releases, and the language model and search engine claims have no accompanying specification. Before writing code against it, verify three things in the repository: the current shape of Resin.KeyValue's public surface, the setup instructions in Resin.WikipediaCommandLine/README.md, and whether your TKey type satisfies the strict total order requirement, since non-primitive keys are hashed to long for page-level storage and collisions there affect correctness.
Community notes