.NET · in-process · AOT-safe

Pagefind search
in pure .NET.

A native .NET port of the Pagefind indexer — build search indexes in-process, no subprocess, no shelling out. Compatible with the official Pagefind JS/WASM query runtime.

nuget ↗
nuget ↗
build a search index — in process
using Pagefind.Net;

var index = new PagefindIndex(new PagefindIndexOptions
{
    Language = "en"
});

index.AddRecord(new PagefindRecord
{
    Url     = "/guide/",
    Title   = "Getting started",
    Content = plainTextBody,
    WeightedSegments =
    [
        new WeightedSegment(h1Text, Weight: 7),
        new WeightedSegment(bodyText, Weight: 1),
    ],
});

await index.WriteAsync("wwwroot");
// writes pagefind/ — ready for pagefind.js

Full Pagefind compatibility.
Zero native dependencies.

pagefind-net reimplements the Pagefind indexer in managed C#, producing the same pagefind/ directory the official JS/WASM query runtime consumes — byte for byte.

in-process
No subprocess

Index generation runs inside your .NET process. No binary to locate, no Process.Start, no exit codes to parse. Just a method call.

pagefind 1.5.2
Byte-compatible
output

Produces identical .pf_meta, .pf_index, and .pf_fragment files to the official Pagefind binary. The standard pagefind.js query runtime works without modification.

zero allocation hot path
Built for
throughput

Zero-allocation tokeniser and stemmer on hot paths. Concurrent AddRecord with O(1) memory pressure and per-record error attribution.

aot + trimming
AOT-ready

No reflection, no dynamic dispatch. Trims cleanly and publishes as a native binary. AOT-compatible end-to-end — tested on Linux, macOS, and Windows.

msbuild
Frontend
package

Pagefind.Net.Frontend ships the Pagefind JS/WASM runtime. An MSBuild target auto-extracts the files into your project on build — no manual steps.

heading boost · anchors
Weighted
segments

Pass WeightedSegments to boost headings and create sub-page anchors — same as the official binary's structured indexing API.


Search that stays
inside your process.

The official Pagefind CLI is a great tool — but calling it from .NET means shelling out: locating a binary, managing a subprocess, parsing exit codes. pagefind-net removes that entirely by running the same logic in-process as a native .NET library.

no Process.Start · no path management
In-process
execution

Index generation is a method call, not a shell command. No binary to ship alongside your app, no path resolution at runtime, no stdout/stderr to parse. Errors surface as typed .NET exceptions, not process exit codes.

linux · macos · windows · arm
No platform
restrictions

The official CLI ships separate platform-specific binaries. pagefind-net runs anywhere .NET runs — any OS, any CPU, any container, any CI runner. One NuGet package, no conditionals, no runtime downloads.

concurrent · per-record errors
First-class .NET
integration

AddRecord is safe to call concurrently from multiple threads. Integrate index generation directly into your ASP.NET Core pipeline, Blazor app, or build system — no inter-process coordination required.

integration guide →
e2e parity tests
Verified
compatibility

The test suite runs both pagefind-net and the official CLI on the same input and diffs the output. Encoding, tokenization, and file layout are verified byte-for-byte. The query side — pagefind.js, your UI, your search component — stays unchanged.


Two packages.
Then index your content.

Add the indexer, point it at your documents, call WriteAsync. Add the frontend package and your MSBuild target handles the rest.

01
Add the indexer

dotnet add package Pagefind.Net — targets net9.0 and later. No native or JavaScript transitive dependencies.

02
Index your documents

Create a PagefindIndex, call AddRecord for each page — concurrently if you like. Pass WeightedSegments to boost headings and generate per-heading anchors.

03
Write the index

Call await index.WriteAsync("wwwroot"). The pagefind/ directory is written and ready for the standard Pagefind JS runtime to query.

04
Ship the frontend

Add Pagefind.Net.Frontend — an MSBuild target extracts pagefind.js and wasm.en.pagefind into your project automatically.

concurrent indexing
var index = new PagefindIndex(
    new PagefindIndexOptions { Language = "en" });

// AddRecord is thread-safe
await Parallel.ForEachAsync(pages, async (page, _) =>
{
    index.AddRecord(new PagefindRecord
    {
        Url     = page.Url,
        Title   = page.Title,
        Content = page.PlainText,
        WeightedSegments =
        [
            new WeightedSegment(page.H1, Weight: 7),
            new WeightedSegment(page.Body, Weight: 1),
        ]
    });
});

await index.WriteAsync("wwwroot");
frontend — programmatic extraction
using Pagefind.Net.Frontend;

// extract pagefind.js + wasm to wwwroot/pagefind
await PagefindFrontend.ExtractToAsync("wwwroot");

In-process.
No subprocess.
Pure .NET.

One NuGet package. Pagefind search indexing that runs inside your .NET process — no shelling out, no binary to ship.