Skip to content

[Integration]: [.NET SDK] ZVec.NET β€” First .NET Core SDK for ZVec (alongside Python & Node.js)Β #603

Description

@ahmedSamir50

Target Framework

.NET

Motivation

Hi ZVec team πŸ‘‹

I've built and published ZVec.NET β€” the first production .NET SDK for ZVec, bringing full vector database capabilities to the .NET ecosystem alongside your existing Python and Node.js SDKs.

NuGet: nuget.org/packages/ZVec.NET
GitHub: github.com/ahmedSamir50/AdamSystems.ZVec.NET
License: MIT (same as ZVec)
Current version: 1.0.0-beta.2+zvec.0.5.1
Why .NET Integration Matters
.NET is a top-5 language ecosystem by developer population β€” over 7 million active developers worldwide (SlashData 2025). It dominates enterprise, government, banking, and healthcare sectors where vector search is increasingly critical for AI-powered features. Yet the .NET ecosystem has historically been underserved by vector database vendors, who typically ship Python and Node.js SDKs first and treat .NET as an afterthought.

ZVec.NET changes this by providing a first-class, production-grade .NET SDK that wraps the full zvec_c_api C interface β€” not a thin P/Invoke wrapper, but a full-featured SDK with typed ODM mapping, DI-first ergonomics, SafeHandle resource safety, and cross-platform native binaries.

Who Benefits
Enterprise .NET developers building AI features (semantic search, RAG pipelines, recommendation engines, anomaly detection) β€” they get a vector database that runs in-process with no Docker, no network overhead, and no external service dependency. ZVec's in-process architecture (like SQLite) is a natural fit for .NET.
The ZVec project β€” listing a .NET SDK alongside Python and Node.js signals ecosystem maturity and expands adoption into the enterprise segment where .NET is dominant. This is the same pattern PostgreSQL (Npgsql), MySQL (Pomelo), and SQLite (SQLitePCLRaw) used to grow their .NET communities.
Edge/mobile developers β€” ZVec.NET already ships native binaries for android-arm64 and android-x64, with MAUI sample apps demonstrating offline RAG on mobile devices. This is a use case Python and Node.js cannot serve.
The broader AI/ML community β€” .NET developers building production RAG systems now have a low-latency, zero-dependency vector database option that works on edge devices, in desktop apps (MAUI), and in cloud services (ASP.NET Core) β€” all from a single NuGet package.
What ZVec.NET Covers
The SDK wraps the full zvec_c_api surface and exposes it as idiomatic C#:

Feature Status
HNSW, Flat, IVF, DiskANN, Vamana, Invert, FTS indexes βœ…
HNSW-RaBitQ (quantized HNSW) β€” with PlatformNotSupportedException gate on ARM βœ…
CRUD (Insert, Update, Upsert, Delete, Fetch) β€” typed + dynamic βœ…
Single + Multi-vector query with RRF/Weighted rerankers βœ…
Hybrid search (dense + sparse) βœ…
Full-text search (FTS) β€” Standard, Jieba, Whitespace tokenizers βœ…
Expression filters (typed: p => p.Category == "x") + dynamic filter builder βœ…
Schema evolution (AddColumn, DropColumn, CreateIndex, DropIndex, Optimize) βœ…
Typed ODM via ZVec.NET.Mapping β€” POCO mapping with [ZVecVector], [ZVecField], [ZVecId] attributes βœ…
DI integration (ASP.NET Core AddZVec() / AddZVecCollection()) βœ…
Health checks (ZVecHealthCheck) βœ…
Sync + Async APIs with CancellationToken βœ…
Cross-platform natives (win-x64, linux-x64, osx-arm64, android-arm64/x64) βœ…
ABI version gate (zvec_check_version + major match) βœ…
Sample apps: ASP.NET Minimal API, MAUI Blazor Hybrid (offline RAG), Console βœ…

Binding Performance
BenchmarkDotNet results (768-dim Flat, 10k docs, win-x64, native ZVec v0.5.1, .NET 8):

Metric .NET (ZVec.NET) Python Node.js
Query (10k, topk=10, no vectors) 2.88 ms 4.33 ms 4.10 ms
Warm query (128 docs) 0.51 ms 0.41 ms 1.59 ms
Batch insert (1000 docs) ~16.8k docs/sec ~7.1k docs/sec ~5.8k docs/sec

The .NET SDK is competitive with β€” and in some cases faster than β€” the official Python and Node.js bindings, thanks to [LibraryImport] source-generated P/Invoke and ReadOnlyMemory pin-based vector pipelines.

Required Interface

ZVec.NET implements no external framework adapter β€” it is a standalone SDK that wraps the zvec_c_api C interface directly. The SDK defines its own interface contract:

Interface Responsibility
IZvecFactory Process-wide initialization (Initialize/Shutdown), collection lifecycle (CreateAndOpen/Open). Implements IDisposable, IAsyncDisposable. Tracks open collections; Shutdown disposes all tracked collections before calling zvec_shutdown.
IZvecCollection<T> Typed per-collection operations: typed CRUD (Insert/Update/Upsert/Delete/Fetch with POCO mapping), typed Query with expression filters (p => p.Category == "demo"), typed DDL (DropColumnAsync(p => p.Year), CreateIndexAsync(p => p.Year, ...)).
IZvecCollection (dynamic) Dynamic operations via ZVecDoc, string field names, ZVecFilterBuilder. Accessible from typed collection via .Untyped.

DI Registration (ASP.NET Core / Generic Host / MAUI)
builder.Services.AddZVec(options => { ... });
builder.Services.AddZVecCollection(options => { ... }); // typed
builder.Services.AddZVecCollection("key", options => { ... }); // keyed dynamic
Supports IConfiguration binding (appsettings.json), health checks (AddCheck("zvec")), and keyed services ([FromKeyedServices("products")]).

Interop Contract
The SDK communicates with ZVec exclusively through the zvec_c_api C ABI:

P/Invoke: [LibraryImport("zvec_c_api")] β€” source-generated marshalling (no runtime reflection).
Handle safety: Collection handles owned by SafeZvecHandle (close-only on Dispose; Destroy deletes on-disk data then closes). ZVecFactory.Shutdown disposes all tracked open collections before calling zvec_shutdown.
Memory model: ReadOnlyMemory on all vector hot paths β€” pinned via Memory.Pin(), passed as native pointer, no intermediate float[] copies on the query pin path.
Concurrency: Optional throttles via MaxConcurrentNativeCalls / MaxConcurrentReads (use SemaphoreSlim when > 0; 0 = unlimited). Native ZVec is already thread-safe.
Error handling: All native return codes mapped to ZVecErrorCode enum; failures throw ZVecNativeException with native error message extraction via zvec_get_last_error(). ABI gate throws ZVecAbiMismatchException on version mismatch.
Platform gates: PlatformNotSupportedException thrown before native call for HNSW-RaBitQ on ARM (requires x86_64 + AVX2) and DiskANN on non-Linux (requires libaio).
Typed ODM (ZVec.NET.Mapping)
The SDK includes a typed ODM layer that maps POCOs to ZVec collections:
public sealed class Product
{
public string Id { get; set; } = "";
public string Title { get; set; } = "";
public string Category { get; set; } = "";

[ZVecVector(768, Metric = ZVecMetricType.Cosine, M = 32, EfConstruction = 256)]
public ReadOnlyMemory<float> Embedding { get; set; }

}

// Schema from POCO
var schema = ZVecCollectionSchemaBuilder.From().Build();

// Typed query with expression filter
var hits = products.Query(p => p.Embedding, queryVec, topK: 10, filter: p => p.Category == "demo");

No VectorStore Abstraction (Yet)
ZVec.NET does not implement Microsoft.Extensions.VectorData.IVectorStore (the new .NET AI abstraction in preview). This is intentional for v1 β€” the SDK wraps ZVec's own API surface idiomatically first. A VectorStore adapter can be added in a future version once the Microsoft.Extensions.VectorData API stabilizes and ZVec is officially listed as a supported provider.

Reference Implementations

Official ZVec SDKs (same C API, different language)

SDK Vector DB Interop DI Typed ODM Mobile RIDs
Npgsql PostgreSQL + pgvector Native P/Invoke βœ… EF Core provider ❌
Milvus .NET SDK Milvus gRPC βœ… ❌ ❌
Qdrant Client .NET Qdrant gRPC βœ… ❌ ❌
SQLitePCLRaw SQLite Native P/Invoke βœ… ❌ βœ…
ZVec.NET ZVec Native P/Invoke ([LibraryImport]) βœ… βœ… (ZVec.NET.Mapping) βœ… (Android)

ZVec.NET's architecture is most similar to SQLitePCLRaw and Npgsql: native P/Invoke wrapping a C ABI, SafeHandle for resource safety, single NuGet with RID-specific native binaries, and DI-first public API. The key differences are:

In-process (like SQLite) rather than client-server (like PostgreSQL/Milvus/Qdrant) β€” making native P/Invoke the only appropriate interop strategy.
Typed ODM β€” a feature Npgsql has via EF Core, but ZVec.NET provides natively via ZVec.NET.Mapping without requiring an ORM.
Mobile RIDs β€” Android ARM64/x64 native binaries, with MAUI sample apps demonstrating offline edge RAG. This is unique among .NET vector DB SDKs.
Competing NuGet Package
There is another .NET package wrapping ZVec β€” Zvec by TheBitBrine. It provides a thinner sync P/Invoke surface using float[] (not ReadOnlyMemory), covers fewer index types (no RaBitQ, DiskANN, Vamana, FTS), and targets desktop RIDs only. ZVec.NET is the more complete SDK with DI, typed ODM, async, expression filters, and mobile support. Both packages wrap the same zvec_c_api.

Steps I Plan to Follow
βœ… Published ZVec.NET on NuGet β€” 1.0.0-beta.2+zvec.0.5.1 (nuget.org/packages/ZVec.NET)
βœ… Published sample apps: ASP.NET Minimal API, MAUI Blazor Hybrid (offline RAG), Console
βœ… Published BenchmarkDotNet results comparing .NET vs Python vs Node.js
βœ… Opened this ecosystem integration issue
⬜ Submit a PR to alibaba/zvec adding ZVec.NET to the README's SDK/ecosystem section (if maintainers are open to it)
⬜ Add .NET code examples alongside Python/Node.js in ZVec documentation (if docs accept community contributions)
⬜ Coordinate with maintainers on ABI version pinning strategy for future ZVec releases
⬜ Implement Microsoft.Extensions.VectorData.IVectorStore adapter once the API stabilizes
⬜ Announce on ZVec community channels (Discord/Discussions, if they exist)

Metadata

Metadata

Assignees

Labels

integrationintegrate with AI framework or database

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions