speedkey

March 27, 2026 ยท View on GitHub

npm license

Valkey/Redis client with direct NAPI bindings based on valkey-glide core. No IPC socket - Rust talks directly to Node.js via NAPI.

This is the client layer for glide-mq. It will be replaced by the official valkey-glide NAPI client once it ships upstream. Until then, speedkey provides the same typed API surface that glide-mq depends on.

Note: speedkey will be replaced by valkey-glide when glide completes its migration to NAPI. The API surface is designed to align with valkey-glide to minimize migration effort.

Install

npm install @glidemq/speedkey

Requires valkey-bundle for Search, JSON, and Bloom module support:

docker run -d -p 6379:6379 valkey/valkey-bundle

Module Support

Search (GlideFt) - 5 commands

CommandMethodDescription
FT.CREATEGlideFt.create()Create a search index with HASH or JSON schema
FT.SEARCHGlideFt.search()Search an index with filters and KNN vector queries
FT.DROPINDEXGlideFt.dropindex()Delete an index
FT.INFOGlideFt.info()Get index metadata
FT._LISTGlideFt.list()List all indexes

Search 1.1/1.2 options supported:

FT.CREATE: score, language, skipInitialScan, minStemSize, withOffsets/noOffsets, noStopWords/stopWords, punctuation. Fields: sortable, nostem, weight, withsuffixtrie/nosuffixtrie.

FT.SEARCH: nocontent, dialect, verbatim, inorder, slop, sortby, scorer.

Not available in valkey-search: FT.AGGREGATE, FT.EXPLAIN, FT.EXPLAINCLI, FT.PROFILE, FT.ALIASADD, FT.ALIASDEL, FT.ALIASUPDATE, FT._ALIASLIST. These are Redis Search (redis-stack) only.

JSON (GlideJson) - 22 commands

Full JSON document manipulation: SET, GET, MGET, MSET, DEL, FORGET, TYPE, CLEAR, TOGGLE, STRLEN, STRAPPEND, ARRAPPEND, ARRINSERT, ARRLEN, ARRPOP, ARRTRIM, ARRINDEX, NUMINCRBY, NUMMULTBY, OBJLEN, OBJKEYS, RESP, DEBUG.

Bloom Filter (GlideBf) - 9 commands

CommandMethodDescription
BF.RESERVEGlideBf.reserve()Create a bloom filter with error rate and capacity
BF.ADDGlideBf.add()Add an item (returns true if new)
BF.MADDGlideBf.madd()Add multiple items
BF.EXISTSGlideBf.exists()Check if item may exist
BF.MEXISTSGlideBf.mexists()Check multiple items
BF.INFOGlideBf.info()Get filter metadata
BF.INSERTGlideBf.insert()Add items with auto-create options
BF.CARDGlideBf.card()Get item count
BF.LOADGlideBf.load()Restore a serialized filter

Usage

import {
  GlideClient,
  GlideClusterClient,
  GlideJson,
  GlideFt,
  GlideBf,
} from "@glidemq/speedkey";

// Standalone
const client = await GlideClient.createClient({
  addresses: [{ host: "localhost", port: 6379 }],
});

// Cluster
const cluster = await GlideClusterClient.createClient({
  addresses: [{ host: "127.0.0.1", port: 7000 }],
});

JSON

await GlideJson.set(client, "user:1", "$", '{"name":"Alice","age":30}');
const user = await GlideJson.get(client, "user:1", { path: "$" });

// Batch set
await GlideJson.mset(client, [
  { key: "user:2", path: "$", value: '{"name":"Bob"}' },
  { key: "user:3", path: "$", value: '{"name":"Carol"}' },
]);
// Create index with vector field (required by valkey-search)
await GlideFt.create(client, "docs-idx", [
  { type: "TAG", name: "category" },
  { type: "NUMERIC", name: "score" },
  {
    type: "VECTOR", name: "embedding",
    attributes: {
      algorithm: "HNSW",
      dimensions: 384,
      distanceMetric: "COSINE",
      type: "FLOAT32",
    },
  },
], { dataType: "HASH", prefixes: ["doc:"] });

// Store document with embedding
const embedding = new Float32Array(384); // from your embedding model
await client.hset("doc:1", {
  category: "ml",
  score: "95",
  embedding: Buffer.from(embedding.buffer),
});

// KNN search with pre-filter
const [total, results] = await GlideFt.search(
  client, "docs-idx",
  "@category:{ml}=>[KNN 5 @embedding $VEC AS dist]",
  { params: [{ key: "VEC", value: Buffer.from(embedding.buffer) }] },
);

Bloom Filter

await GlideBf.reserve(client, "emails", 0.001, 100000);
await GlideBf.add(client, "emails", "alice@example.com");

const exists = await GlideBf.exists(client, "emails", "alice@example.com"); // true
const missing = await GlideBf.exists(client, "emails", "unknown@x.com");   // false

const info = await GlideBf.info(client, "emails");
// { capacity: 100000, size: ..., numberOfFilters: 1, numberOfItems: 1, expansionRate: 2 }

Core API

speedkey exposes the full valkey-glide BaseClient API (200+ commands) for strings, hashes, lists, sets, sorted sets, streams, HyperLogLog, geo, pub/sub, scripting, and more. See the valkey-glide documentation for the complete command reference.

License

Apache-2.0