Valkey utilities for Node.js services: cache helpers, Bloom filters, dynamic configuration, and sliding-window rate limiting.
pnpm add valkyries @valkey/valkey-glidevalkyries is ESM-only and requires Node.js 24 or newer.
By default the package reads VALKEY_URL, falling back to redis://localhost:6379.
Specialized URLs can split traffic by data type:
VALKEY_CACHE_URL=redis://localhost:6379
VALKEY_RATE_LIMITER_URL=redis://localhost:6379
VALKEY_DYNAMIC_CONFIG_URL=redis://localhost:6379Bloom filters require Valkey with the Bloom module. For local development and CI, use Valkey Bundle:
docker run --rm -p 6379:6379 valkey/valkey-bundle:latestimport { ValkeyCache } from "valkyries";
const cache = new ValkeyCache({ prefix: "users", ttlSeconds: 300 });
const getUser = cache.cacheGetByAny(async (id) => {
return await loadUserFromDatabase(id);
});
const user = await getUser("user_123");
await cache.invalidateCacheGetByAny("user_123");Cache keys are normalized with trim().toLowerCase(). Use keySerializer for composite keys.
import { ValkeyBloomFilter } from "valkyries";
const filter = new ValkeyBloomFilter({
name: "users",
capacity: 1_000_000,
errorRate: 0.01,
});
await filter.ensureExists();
await filter.add(["user_123"]);
const maybeExists = await filter.existsIfReady("users:ready", "user_123");null means the filter is missing or not ready and callers should fall back to the authoritative store.
import { DynamicConfig } from "valkyries";
const flags = new DynamicConfig({
key: "feature-flags",
fieldTypes: { enabled: "boolean", sampleRate: "number" },
defaultFields: { enabled: false, sampleRate: 0 },
});
await flags.waitForInitialization();
await flags.setField("enabled", true);Dynamic config stores fields in a Valkey hash and publishes changes over pub/sub.
import { RateLimiter } from "valkyries";
const limiter = new RateLimiter({ prefix: "login", ttlSeconds: 60 });
const { limited, counts } = await limiter.addAndCheck(["ip:127.0.0.1"], 10);addAndCheck() increments first and blocks when any post-add count is greater than or equal to the threshold.
Every class accepts an optional GlideClient for tests or custom connection management:
import { GlideClient } from "@valkey/valkey-glide";
import { ValkeyCache, glideConfigFromUrl } from "valkyries";
const client = await GlideClient.createClient(glideConfigFromUrl("redis://localhost:6379"));
const cache = new ValkeyCache({ prefix: "custom", ttlSeconds: 60, client });Call closeValkeyClients() to close package-managed clients.