---
title: "Getting started with OneNLP"
url: https://recursiveai.org/onenlp/docs/getting-started/
description: "Install OneNLP for .NET 10, find the language, sentences, numbers and dates of a text with the core package alone, then add a model package for entities…"
version: "1.0.0"
---

# Getting started with OneNLP

Install OneNLP for .NET 10, find the language, sentences, numbers and dates of a text with the core package alone, then add a model package for entities, lemmas and the parse, and another for sentence embeddings. Every program below was run on the 1.0.0 packages from NuGet, and the output shown is what it printed.

## Install

OneNLP targets `net10.0`, so you need the .NET 10 SDK.

```shell
dotnet new console -o NlpStart
cd NlpStart
dotnet add package RecursiveAI.OneNlp
```

The core package depends on the .NET base class library and `RecursiveAI.OneFont` only, and contains no native code. It holds the tokenizers, word and sentence segmentation, rule matching, the recognizers and language identification for 75 languages. Trained models come in their own packages, one per language or task. Nothing is ever downloaded: a model is delivered with its package.

## With the core package alone

`Program.cs`:

```csharp
using RecursiveAI.OneNlp;

string text = "Angela Merkel met Emmanuel Macron in Paris on 5 March 2026. The deal cost $5m.";

// Language ID, sentences and tokens: in the core package, no model needed.
Console.WriteLine(Nlp.DetectLanguage(text));
Console.WriteLine(Nlp.DetectLanguage("Der Vertrag wurde gestern in Berlin unterschrieben."));

foreach (Span s in Nlp.Sentences(text))
    Console.WriteLine($"[{s.StartChar}..{s.EndChar}) {s.Text}");

Console.WriteLine(string.Join(" | ", Nlp.Tokens(text).Take(8)));

// Recognizers: numbers, money, dates, resolved to values.
foreach (Quantity q in Nlp.Quantities(text))
    Console.WriteLine($"{q.Kind} {q.Value} {q.Currency}");

DateTimeOffset today = new(2026, 3, 18, 10, 30, 0, TimeSpan.Zero);
DateRange? when = Nlp.ParseDate("the first Monday after Easter 2027", today);
Console.WriteLine(when?.Start.ToString("yyyy-MM-dd"));

// A verb that needs a model throws and names the package to add.
try
{
    Nlp.Entities(text);
}
catch (InvalidOperationException e)
{
    Console.WriteLine(e.Message);
}
```

`dotnet run` prints:

```text
en
de
[0..59) Angela Merkel met Emmanuel Macron in Paris on 5 March 2026.
[60..78) The deal cost $5m.
Angela | Merkel | met | Emmanuel | Macron | in | Paris | on
Money 5000000 USD
2027-03-29
No model is available for language 'en'. Add the NuGet package RecursiveAI.OneNlp.Models.English (or RecursiveAI.OneNlp.Models.Multilingual); models are never downloaded.
```

Offsets are UTF-16 offsets into the string you passed in. Relative dates need a reference date, which you pass: Easter 2027 is 28 March, so the first Monday after it is 29 March. The exception is a `ModelNotAvailableException`, an `InvalidOperationException` that names the package to add.

## Add a model: entities, lemmas and the parse

```shell
dotnet add package RecursiveAI.OneNlp.Models.English
dotnet add package RecursiveAI.OneNlp.Models.Embeddings
```

`RecursiveAI.OneNlp.Models.English` is the English fast tier: tags, morphology, lemmas, the dependency parse and entities. `RecursiveAI.OneNlp.Models.Embeddings` is the default English sentence embedder for `Nlp.Embed` (bge-small-en-v1.5, MIT). There is nothing to register: add the package and the `Nlp` verbs use it for text in its language.

`Program.cs`:

```csharp
using RecursiveAI.OneNlp;

string text = "Angela Merkel met Emmanuel Macron in Paris on 5 March 2026. The deal cost $5m.";

// With RecursiveAI.OneNlp.Models.English: entities, lemmas and the full analysis.
foreach (Span e in Nlp.Entities(text))
    Console.WriteLine($"{e.Label} {e.Text} [{e.StartChar}..{e.EndChar})");

Console.WriteLine(string.Join(" ", Nlp.Lemmas("The cats were running.")));

Doc doc = Nlp.Analyze(text);
foreach (Token t in doc.Take(5))
    Console.WriteLine($"{t.Text} {t.Pos} {t.Lemma} {t.Dep} -> {t.Head.Text}");

// With RecursiveAI.OneNlp.Models.Embeddings: sentence vectors.
float[] a = Nlp.Embed("how do I reset my password");
float[] b = Nlp.Embed("I forgot my password and can't log in");
float[] c = Nlp.Embed("what time does the bakery open");
Console.WriteLine($"{a.Length} dimensions");
Console.WriteLine($"password / login: {Cosine(a, b):F2}");
Console.WriteLine($"password / bakery: {Cosine(a, c):F2}");

static float Cosine(float[] x, float[] y)
{
    float dot = 0, nx = 0, ny = 0;
    for (int i = 0; i < x.Length; i++) { dot += x[i] * y[i]; nx += x[i] * x[i]; ny += y[i] * y[i]; }
    return dot / MathF.Sqrt(nx * ny);
}
```

`dotnet run` prints:

```text
PER Angela Merkel [0..13)
PER Emmanuel [18..26)
LOC Paris [37..42)
the cat be run .
Angela PROPN Angela compound -> Merkel
Merkel PROPN Merkel nsubj -> met
met VERB meet root -> met
Emmanuel PROPN Emmanuel xcomp -> met
Macron PROPN Macron obj -> met
384 dimensions
password / login: 0.86
password / bakery: 0.49
```

This is the model’s real output on this sentence, mistakes included: it marks “Emmanuel” alone as a person and attaches “Macron” as the object. `Nlp.Analyze` returns a `Doc` with the tokens, sentences, tags, lemmas, the parse and the entities from one call.

## Another language

Each fast-tier language is its own package: `RecursiveAI.OneNlp.Models.French`, `.German`, `.Spanish`, `.Portuguese`, `.Dutch`, `.Italian`, `.Chinese`, `.Turkish` and `.Hindi`. With `RecursiveAI.OneNlp.Models.German` in place of the English model:

```csharp
using RecursiveAI.OneNlp;

string text = "Die Bäckerei Sonnenschein in Hamburg eröffnet am 3. Mai eine zweite Filiale. Der Umbau kostete 12.500 Euro.";

Console.WriteLine(Nlp.DetectLanguage(text));
foreach (Span e in Nlp.Entities(text))
    Console.WriteLine($"{e.Label} {e.Text}");
Console.WriteLine(string.Join(" ", Nlp.Lemmas(text).Take(8)));

foreach (Quantity q in Nlp.Quantities(text, Language.German))
    Console.WriteLine($"{q.Kind} {q.Value} {q.Currency}");

DateTimeOffset today = new(2026, 4, 20, 9, 0, 0, TimeSpan.Zero);
Console.WriteLine(Nlp.ParseDate("am 3. Mai", today, Language.German)?.Start.ToString("yyyy-MM-dd"));
```

`dotnet run` prints:

```text
de
ORG Bäckerei Sonnenschein
LOC Hamburg
MISC Euro
der Bäckerei Sonnenschein in Hamburg eröffnen an der
Ordinal 3 
Ordinal 2 
Money 12500 EUR
2026-05-03
```

The recognizers take the language as an argument (`Nlp.Quantities(text)` without one reads English). The German model splits “am” into two words, with the lemmas “an” and “der”.

## The accurate tiers

Two packages cover many languages with one model:

- `RecursiveAI.OneNlp.Models.Multilingual` is the distilled accurate tier: syntax and entities for English, German, French, Spanish, Portuguese, Italian, Dutch, Turkish and Chinese, plus open-type entities (`Nlp.Entities(text, types)`, labels named at runtime).
- `RecursiveAI.OneNlp.Models.Multilingual.Large` is the base-size accurate tier: syntax for 84 languages and entities for 19. It is about 3.5 GB across 19 packages; reference the root package only, and deploy the complete publish directory.

```shell
dotnet add package RecursiveAI.OneNlp.Models.Multilingual.Large
```

When a fast-tier package for the text’s language is referenced, the `Nlp` verbs use it; otherwise they use the multilingual accurate tier. See [Model packages](https://recursiveai.org/onenlp/docs/model-packages/) for the order and for loading one package’s pipeline directly.

## Where next

- [How the API reads](https://recursiveai.org/onenlp/docs/reads-like/): the happy path, the low-level `Pipeline` and `Tokenizer`.
- [Recognizers](https://recursiveai.org/onenlp/docs/recognizers/) and [Language identification](https://recursiveai.org/onenlp/docs/language-id/).
- [Sentence embeddings](https://recursiveai.org/onenlp/docs/embeddings/), including the multilingual embedder.
- [Training and recipes](https://recursiveai.org/onenlp/docs/training/): train every neural part with the API that trained the shipped models.
- [Results table](https://recursiveai.org/onenlp/docs/results-table/): every measured row, including the rows behind.
