---
title: "Getting started with OneIndex"
url: https://recursiveai.org/oneindex/docs/getting-started/
description: "Install OneIndex 0.4.0-preview.2 for .NET 10, index a few objects and search them, in C# with no server and no native code. OneIndex is an embedded search…"
version: "0.4.0-preview.2"
---

# Getting started with OneIndex

Install OneIndex 0.4.0-preview.2 for .NET 10, index a few objects and search them, in C# with no server and no native code. OneIndex is an embedded search engine: full-text (BM25F), vector (HNSW) and hybrid search in one in-process library.

## Before you use it

- **A preview.** In the README’s words: “Everything in the table below works and is tested; APIs and file formats may still change between previews.” Its [overview](https://recursiveai.org/oneindex/docs/overview/) lists what exists and the known gaps.
- **Durability, as the project tests it.** A commit that returns survives a crash or `kill -9` of your process, and a damaged file fails the open with an error naming it instead of returning wrong results. The project’s own testing ran about 890,000 fault-injection schedules and more than 7,000 process kills with no failed open and no lost commit. Its limits: “On a power cut the index may roll back to an earlier commit, but it is never corrupt”, and the kill and fault-injection campaigns run on Linux and macOS only; Windows runs the full test suite on every change. Network and FUSE file systems are not supported. [Durability](https://recursiveai.org/oneindex/docs/durability/).
- **Speed and relevance** against Lucene.NET are measured in [benchmarks](https://recursiveai.org/oneindex/docs/benchmarks/) and [relevance](https://recursiveai.org/oneindex/docs/relevance/), with their conditions.

## Install

The packages target `net10.0`, so you need the .NET 10 SDK, and `dotnet add package` needs `--prerelease` or the exact version.

```shell
dotnet new console -o OneIndexStart && cd OneIndexStart
dotnet add package RecursiveAI.OneIndex --version 0.4.0-preview.2
```

Nine packages share one version:

| Package | What it is |
|---|---|
| `RecursiveAI.OneIndex` | the engine and the happy path; no dependencies beyond .NET |
| `RecursiveAI.OneIndex.Models` | bundled embedder (bge-small-en-v1.5), reranker and sparse encoder on OneModel; a 134 MB package |
| `RecursiveAI.OneIndex.Models.Multilingual` | the multilingual-e5-small embedder, around 100 languages; a 112 MB package |
| `RecursiveAI.OneIndex.Analysis.Asian` | Japanese, Chinese, Korean, Thai, Lao, Khmer and Myanmar segmentation |
| `RecursiveAI.OneIndex.EntityFrameworkCore` | keeps an index in step with `SaveChanges` |
| `RecursiveAI.OneIndex.VectorData` | a vector store for `Microsoft.Extensions.VectorData` |
| `RecursiveAI.OneIndex.Files`, `.Files.Ocr` | folder indexing with citations; OCR for scans |
| `RecursiveAI.OneIndex.Cli` | the `oneindex` tool: `index`, `query`, `static build` |

## A first program

Put this in `Program.cs` and run `dotnet run`:

```csharp
using OneIndex;

// a directory; SearchIndex.InMemory<Invoice>() keeps it in memory
using var index = SearchIndex.Open<Invoice>("data/search");
index.Upsert(new Invoice { Id = "inv-1", Title = "Overdue notice",
                           Body = "Payment from Acme Corp is overdue.",
                           Modified = DateTime.UtcNow, Tags = ["invoice"] });
index.Upsert(new Invoice { Id = "inv-2", Title = "Draft: overdue reminder",
                           Body = "Acme Corp draft, not sent.",
                           Modified = DateTime.UtcNow, Tags = ["invoice", "draft"] });
index.Commit();                                    // atomic and durable

var cutoff = DateTime.UtcNow.AddYears(-1);
// what a user types: words, "phrases", -exclusions
var results = index.Search("overdue \"acme corp\" -draft")
                   .Where(x => x.Tags.Contains("invoice") && x.Modified > cutoff)
                   .Take(10);
foreach (var hit in results)
    Console.WriteLine($"{hit.Id} {hit.Score:F2} {hit.Document.Title}");
Console.WriteLine($"{index.Count} documents");

public class Invoice
{
    [SearchId] public string Id { get; set; } = "";
    [FullText(Boost = 2)] public string Title { get; set; } = "";
    [FullText(Language = "en")] public string Body { get; set; } = "";
    [Filterable, Sortable] public DateTime Modified { get; set; }
    [Keyword, Facet] public string[] Tags { get; set; } = [];
}
```

```text
inv-1 0.69 Overdue notice
2 documents
```

- A source generator inside the package writes the mapping from the attributes at build time, with no reflection, so it is NativeAOT- and trim-safe. Supported types, diagnostics and highlights: [mapping](https://recursiveai.org/oneindex/docs/mapping/).
- `Search(text)` takes what a user types and never throws, whatever is typed: [user text](https://recursiveai.org/oneindex/docs/user-text/). Every word not joined by `OR` must match, typos are forgiven, and the last word also matches as a prefix.
- `Where` is translated to filters and never run; anything it cannot translate throws and names the part: [LINQ filters](https://recursiveai.org/oneindex/docs/linq/).
- `Commit` writes and syncs every new file, then publishes the commit with one atomic rename. Searches see the last commit. One writer per directory; reader processes are fine.
- `TotalHits` is a lower bound unless you add `CountExactly()`.

## Next

- [Full-text search in C#](https://recursiveai.org/oneindex/cookbook/full-text-search-csharp/): typos, facets and highlights.
- [Vector search in .NET](https://recursiveai.org/oneindex/cookbook/vector-search-dotnet/) and [hybrid search with reranking](https://recursiveai.org/oneindex/cookbook/hybrid-search-reranking-csharp/), with the bundled models.
- [Search over EF Core entities](https://recursiveai.org/oneindex/cookbook/search-ef-core-entities/) and [a folder of files with citations](https://recursiveai.org/oneindex/cookbook/search-folder-files-citations-csharp/).
- Coming from Lucene.NET: [the migration recipe](https://recursiveai.org/oneindex/cookbook/migrate-from-lucene-net/).
- Every topic: [the docs](https://recursiveai.org/oneindex/docs/), starting with [architecture](https://recursiveai.org/oneindex/docs/architecture/).
