Zvec inspired lightweight, lightning-fast, in-process vector database in Go
Go
0
284 commits
updated Sep 23, 2026
xvec is an embedded vector database vibe-coded with reference to Alibaba zvec. It provides durable local storage and runs inside your application without CGO, a separate database server, or prebuilt native libraries.
[!WARNING] xvec is experimental and is not compatible with zvec's API or disk format. Unless you specifically need a pure-Go implementation, please use zvec-go.
xvec requires Go 1.27 or later.
go get github.com/gorse-io/xvec
Then import it in your application:
import "github.com/gorse-io/xvec"
The following program creates a local collection, stores vectors with metadata, and returns the two nearest documents.
package main
import (
"context"
"fmt"
"log"
"github.com/gorse-io/xvec"
)
func main() {
ctx := context.Background()
schema := xvec.NewCollectionSchema("articles",
xvec.NewField("title", xvec.DataTypeString),
xvec.NewField("category", xvec.DataTypeString),
xvec.FieldSchema{
Name: "embedding",
DataType: xvec.DataTypeVectorFP32,
Dimension: 3,
Index: xvec.NewFlatIndexParams(xvec.MetricTypeCosine),
},
)
collection, err := xvec.CreateAndOpen(
ctx,
"./data/articles",
schema,
xvec.NewCollectionOptions(),
)
if err != nil {
log.Fatal(err)
}
defer collection.Close()
_, err = collection.Insert(ctx, []xvec.Document{
{
PrimaryKey: "go",
Fields: map[string]any{
"title": "The Go Programming Language",
"category": "programming",
"embedding": xvec.VectorFP32{1.0, 0.1, 0.0},
},
},
{
PrimaryKey: "vector",
Fields: map[string]any{
"title": "Vector Search Fundamentals",
"category": "search",
"embedding": xvec.VectorFP32{0.9, 0.2, 0.1},
},
},
{
PrimaryKey: "sql",
Fields: map[string]any{
"title": "Database Internals",
"category": "database",
"embedding": xvec.VectorFP32{0.0, 0.2, 1.0},
},
},
})
if err != nil {
log.Fatal(err)
}
results, err := collection.Query(ctx, xvec.VectorQuery{
Field: "embedding",
DenseVector: xvec.VectorFP32{1.0, 0.0, 0.0},
TopK: 2,
Projection: xvec.Projection{
OutputFields: []string{"title", "category"},
},
})
if err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Printf("%s: %s (score %.4f)\n",
result.PrimaryKey,
result.Fields["title"],
result.Score,
)
}
}
The collection is persisted under ./data/articles. Reopen it after restarting
your application with:
collection, err := xvec.Open(
context.Background(),
"./data/articles",
xvec.NewCollectionOptions(),
)
Use Insert, Upsert, Update, and Delete for document mutations. Call
Flush to publish an immutable segment and Optimize to compact stored data;
Close synchronizes pending WAL records. Set CollectionOptions.WALSyncEvery
to synchronize automatically after a chosen number of successful records; zero
disables automatic record-count-based synchronization. Query also accepts
PrimaryKey as a vector target, a single FTS clause, or a filter-only request
with no target. MultiQuery fuses dense, sparse, primary-key-vector, and FTS
branches over one snapshot.
| Index | Best for |
|---|---|
| Flat | Exact search and small collections |
| HNSW | General-purpose low-latency ANN search |
| IVF | Tunable approximate search with list probing |
| IVF-RaBitQ | Inverted-file probing with memory-efficient RaBitQ scoring |
| Vamana | Graph-based search with deterministic native persistence |
| DiskANN | Disk-backed graph search with bounded node caching |
Dense vectors support FP16 and FP32 storage, plus supported scalar quantization options. Sparse vectors support exact Flat and HNSW inner-product search. See the Go reference for the complete API and the documentation homepage for project benchmarks.
Go
74.8%
Assembly
19.9%
C
4.9%
Zvec inspired lightweight, lightning-fast, in-process vector database in Go
Go
0
284 commits
updated Sep 23, 2026
xvec is an embedded vector database vibe-coded with reference to Alibaba zvec. It provides durable local storage and runs inside your application without CGO, a separate database server, or prebuilt native libraries.
[!WARNING] xvec is experimental and is not compatible with zvec's API or disk format. Unless you specifically need a pure-Go implementation, please use zvec-go.
xvec requires Go 1.27 or later.
go get github.com/gorse-io/xvec
Then import it in your application:
import "github.com/gorse-io/xvec"
The following program creates a local collection, stores vectors with metadata, and returns the two nearest documents.
package main
import (
"context"
"fmt"
"log"
"github.com/gorse-io/xvec"
)
func main() {
ctx := context.Background()
schema := xvec.NewCollectionSchema("articles",
xvec.NewField("title", xvec.DataTypeString),
xvec.NewField("category", xvec.DataTypeString),
xvec.FieldSchema{
Name: "embedding",
DataType: xvec.DataTypeVectorFP32,
Dimension: 3,
Index: xvec.NewFlatIndexParams(xvec.MetricTypeCosine),
},
)
collection, err := xvec.CreateAndOpen(
ctx,
"./data/articles",
schema,
xvec.NewCollectionOptions(),
)
if err != nil {
log.Fatal(err)
}
defer collection.Close()
_, err = collection.Insert(ctx, []xvec.Document{
{
PrimaryKey: "go",
Fields: map[string]any{
"title": "The Go Programming Language",
"category": "programming",
"embedding": xvec.VectorFP32{1.0, 0.1, 0.0},
},
},
{
PrimaryKey: "vector",
Fields: map[string]any{
"title": "Vector Search Fundamentals",
"category": "search",
"embedding": xvec.VectorFP32{0.9, 0.2, 0.1},
},
},
{
PrimaryKey: "sql",
Fields: map[string]any{
"title": "Database Internals",
"category": "database",
"embedding": xvec.VectorFP32{0.0, 0.2, 1.0},
},
},
})
if err != nil {
log.Fatal(err)
}
results, err := collection.Query(ctx, xvec.VectorQuery{
Field: "embedding",
DenseVector: xvec.VectorFP32{1.0, 0.0, 0.0},
TopK: 2,
Projection: xvec.Projection{
OutputFields: []string{"title", "category"},
},
})
if err != nil {
log.Fatal(err)
}
for _, result := range results {
fmt.Printf("%s: %s (score %.4f)\n",
result.PrimaryKey,
result.Fields["title"],
result.Score,
)
}
}
The collection is persisted under ./data/articles. Reopen it after restarting
your application with:
collection, err := xvec.Open(
context.Background(),
"./data/articles",
xvec.NewCollectionOptions(),
)
Use Insert, Upsert, Update, and Delete for document mutations. Call
Flush to publish an immutable segment and Optimize to compact stored data;
Close synchronizes pending WAL records. Set CollectionOptions.WALSyncEvery
to synchronize automatically after a chosen number of successful records; zero
disables automatic record-count-based synchronization. Query also accepts
PrimaryKey as a vector target, a single FTS clause, or a filter-only request
with no target. MultiQuery fuses dense, sparse, primary-key-vector, and FTS
branches over one snapshot.
| Index | Best for |
|---|---|
| Flat | Exact search and small collections |
| HNSW | General-purpose low-latency ANN search |
| IVF | Tunable approximate search with list probing |
| IVF-RaBitQ | Inverted-file probing with memory-efficient RaBitQ scoring |
| Vamana | Graph-based search with deterministic native persistence |
| DiskANN | Disk-backed graph search with bounded node caching |
Dense vectors support FP16 and FP32 storage, plus supported scalar quantization options. Sparse vectors support exact Flat and HNSW inner-product search. See the Go reference for the complete API and the documentation homepage for project benchmarks.
Go
74.8%
Assembly
19.9%
C
4.9%