Skip to content

Releases: jaredwray/keyv

v6.0.0-rc.1

Choose a tag to compare

@jaredwray jaredwray released this 03 Aug 19:15
fffd44b

keyv v6.0.0-rc.1 — 2026-08-03

Promote 6.0 to release candidate: Cloudflare KV adapter, MySQL fixes, and a full dependency refresh.

All published @keyv/* adapters release in lockstep at this version. @keyv/website is private and not published.

⚠ BREAKING CHANGES

  • mysql: keys are now stored as VARBINARY (6e519b4, #2015; f579073, #2016)
    Migration: @keyv/mysql tables created under 6.0.0-beta.4 use the previous key column type. Recreate the keyv table, or ALTER the key column to VARBINARY, before upgrading.
  • keyv: checkExpired now defaults to true (f067213, #1984)
    Migration: expired keys are now checked and cleared by default. Pass checkExpired: false to restore the previous behavior.
  • keyv: removed the namespace removeKeyPrefix behavior for v6 (73fd79b, #2013)
    Migration: keys are no longer stripped of their namespace prefix on read. If you relied on the stripped form, read the full namespaced key.

Features

  • add Cloudflare Workers KV storage adapter (e004467, #1985)

    import { createKeyv } from "@keyv/cloudflare-kv";
    
    // REST mode — from any Node.js process
    const keyv = createKeyv({
      mode: "rest",
      accountId: process.env.CF_ACCOUNT_ID,
      namespaceId: process.env.CF_KV_NAMESPACE_ID,
      apiToken: process.env.CF_API_TOKEN,
    });
    // Or "bind" mode inside a Worker: createKeyv({ kvNamespace: env.MY_KV })
  • mysql: move to async config changes (b775072, #2018)

  • keyv: add the built-in adapters to the docs (2e03276, #1983)

  • mysql: add docs (e07dc4c, #2019)

Bug Fixes

Documentation

  • add keyv-s3fifo to third-party storage adapters (fb420e7, #2020)

Internal

  • refactor: add KeyvAny/KeyvAnyArray types and replace explicit any (49ed583, #2010)
  • 34 dependency and tooling upgrades across the monorepo — highlights: TypeScript 6→7, pnpm 11.5→11.18, better-sqlite3 12→13 (N-API, drops prebuild-install), mongodb 7.4→7.5, mysql2 3.22→3.23, iovalkey 0.3→0.4, @redis/client 6.0→6.1, hookified 3.0.1→3.0.2, actions/setup-node v6→v7, and the Node engines floor raised to ≥ 22.19.0. Full inventory below.

Contributors

Full List of Changes

Full diff: v6.0.0-beta.4...v6.0.0-rc.1

v6.0.0-beta.4

Choose a tag to compare

@jaredwray jaredwray released this 18 Jun 22:23
088b23d

Keyv v6.0.0-beta.4 — 2026-06-18

Finalize the v6 storage-adapter API (ttl → expires) and complete the cross-adapter code/test review.

⚠ BREAKING CHANGES

  • Storage adapters now use expires (absolute epoch-ms timestamp) instead of a relative ttl. (da9c08f, #1981)
    Migration: if you call a storage adapter directly or implement a custom one, read the absolute expires value from the entry envelope instead of accepting a ttl argument. The Keyv core API is unchanged — it continues to derive expires from the value envelope, so typical keyv.set(key, value, ttl) usage is unaffected.

Features

  • bigmap: wire up Hookified events — BigMap now emits SET, DELETE, and CLEAR via the new BigMapEvents enum. (b88d03f, #1977)

    import { BigMap, BigMapEvents } from '@keyv/bigmap';
    
    const map = new BigMap<string>();
    map.on(BigMapEvents.SET, (key, value) => console.log('set', key, value));
    map.on(BigMapEvents.DELETE, (key) => console.log('deleted', key));
    
    map.set('a', '1');  // → "set a 1"
    map.delete('a');    // → "deleted a"

    Also renames the exported MapInterfacee type to MapInterface (typo fix — safe within the v6 beta).

Bug Fixes

  • etcd: support the grpc-gateway v2 error format for etcd 3.6 compatibility. (dcb64bd, #1964)
  • dynamo: strip the namespace prefix in the iterator and align tests/docs. (75198aa, #1965)
  • etcd: return undefined for missing values and align tests/docs. (1e84580, #1966)
  • mysql: return undefined instead of null, guard getMany, and align tests/docs. (d76926b, #1969)

Documentation

  • keyv: fix README API accuracy and strengthen the code/test review. (685bc77, #1979)
  • keyv: add a jsDelivr badge to the README. (418ce7a, #1963)

Internal

  • dynamo: code clean up and minor fixes. (9048a87, #1970)
  • etcd: code clean up and documentation. (aed5638, #1972)
  • postgres: code/test review for @keyv/postgres. (9fa6847, #1971)
  • redis: full code and test review cleanup. (480a560, #1974)
  • memcache: add an error handler. (394e254, #1973)
  • memcache: uniform test suite, fix namespace docs, validate API. (95612fc, #1967)
  • mongo: uniform test suite, fix README API docs. (0240400, #1968)
  • mongo: documentation and fixes (includes #1980 review follow-ups). (f31850d, #1976)
  • sqlite: full code and test review cleanup. (8539cfd, #1975)
  • valkey: full code and test review. (e8a3ffa, #1978)

Contributors

Full List of Changes

  • feat: adding in jsDelivr badge for Keyv by @jaredwray in #1963
  • etcd - fix: support grpc-gateway v2 error format for etcd 3.6 compatibility by @jaredwray in #1964
  • dynamo - fix: strip namespace prefix in iterator and align tests/docs by @jaredwray in #1965
  • etcd - fix: return undefined for missing values and align tests/docs by @jaredwray in #1966
  • memcache - test: uniform test suite, fix namespace docs, validate API by @jaredwray in #1967
  • mongo - test: uniform test suite, fix README API docs by @jaredwray in #1968
  • mysql - fix: return undefined not null, guard getMany, and align tests/docs by @jaredwray in #1969
  • dynamo - chore: code clean up and minor fixes by @jaredwray in #1970
  • etcd - chore: code clean up and documentation by @jaredwray in #1972
  • postgres - refactor: code/test review for @keyv/postgres by @jaredwray in #1971
  • redis - chore: full code and test review cleanup by @jaredwray in #1974
  • memcache - chore: adding in error handler by @jaredwray in #1973
  • sqlite - refactor: full code and test review cleanup by @jaredwray in #1975
  • keyv - docs: fix README API accuracy and strengthen code/test review by @jaredwray in #1979
  • valkey - refactor: full code and test review by @jaredwray in #1978
  • bigmap - feat: wire up hookified events and complete code/test review by @jaredwray in #1977
  • mongo - chore: documentation and fixes by @jaredwray in #1976
  • keyv (breaking) - storage adapters now only use expires instead of ttl by @jaredwray in #1981

Full diff: v6.0.0-beta.3...v6.0.0-beta.4

v6.0.0-beta.3

Choose a tag to compare

@jaredwray jaredwray released this 11 Jun 20:24
5414c14

Keyv v6.0.0-beta.3

This release rolls up the entire v6 beta cycle — everything merged since v6.0.0-alpha.3. v6 is a major, ground-up modernization of Keyv: a leaner core, a new raw-data API, first-class capability detection, telemetry, two new encryption packages, a dependency-free etcd adapter, and a wave of breaking dependency upgrades across the monorepo.

Heads up: v6 contains a number of breaking changes vs. v5. If you are upgrading from v5, read the v5 → v6 migration guide alongside these notes.


Highlights

  • 🔐 Two new encryption packages@keyv/encrypt-node (Node.js crypto) and @keyv/encrypt-web (Web Crypto API), with a shared wire format so they're cross-compatible.
  • 🧩 Raw data APIgetRaw / getManyRaw / setRaw / setManyRaw for working directly with the stored { value, expires } envelope.
  • 🔎 Capability detectiondetectKeyv, detectKeyvStorage, detectKeyvCompression, detectKeyvSerialization, detectKeyvEncryption helpers.
  • 📊 Stats / telemetry overhaul — aggregate counters plus LRU-bounded per-key frequency maps.
  • 🧼 Key sanitization — opt-in protection against SQL/Mongo/path-traversal/control-character injection in keys and namespaces.
  • 🪝 Hookified everywhere — unified events + pre/post hooks across the core and every adapter, now including setMany, deleteMany, clear, and disconnect.
  • 🌐 Dependency-free etcd adapter — talks to etcd v3 over its HTTP/JSON gateway via an in-house client (no etcd3).
  • ⚙️ Optional serialization and no key-prefixing in core for a smaller, faster default path.
  • 🏗️ Build & toolchain modernization — moved to tsdown, TypeScript 6, and a refreshed release pipeline (OIDC publishing).
  • 📦 Major dependency upgrades across Redis, MongoDB, MySQL, Postgres, DynamoDB, msgpackr, hookified, hashery, and more.

⚠️ Breaking Changes

Core

  • StoredData and StoredDataRaw types removed. Use the KeyvValue<T> envelope ({ value, expires? }) and the new raw API instead. (#1929)
  • Keys are no longer prefixed in core. Namespacing/prefixing is now handled by the storage adapters that need it, not the core. (#1899)
  • get no longer checks expiry by default. Expiration is evaluated lazily/where appropriate to keep the hot path fast; expired entries still resolve to undefined through the normal read paths. To re-enable core-level expiry checks, set the checkExpired: true option. (#1923)
  • Moved to Hookified for events + hooks. Replaces the old EventEmitter base across core and adapters. (#1900)
  • .set() now returns a boolean instead of the instance. (#1904)
  • Iterator API simplified and various method signatures cleaned up. (#1902)
  • setRaw / setManyRaw no longer take a ttl argument — set expires on the value envelope instead. (#1905)
  • opts removed from KeyvStorageAdapter and the opts property removed from the Keyv class. (#1906)

Adapters & tooling (dependency bumps that change minimums)

  • @redis/client upgraded to v6 (breaking). (#1954)
  • hookified upgraded to v3 (breaking) across the monorepo. (#1957)
  • hashery upgraded to v2 in BigMap (breaking). (#1956)
  • msgpackr upgraded to v2 in @keyv/serialize-msgpackr (breaking). (#1958)
  • bignumber.js upgraded to v11 in the test-suite (breaking). (#1955)
  • docula upgraded to v2 for the website (breaking). (#1947)
  • Code-quality deps, GitHub Actions, and build tooling upgraded (some breaking minimum versions). (#1944, #1946, #1945)
  • TypeScript 6 is now used to build the monorepo. (#1933)
  • test-suite v6 overhaul — compliance tests rewritten for the v6 API. If you maintain a third-party adapter against @keyv/test-suite, expect changes. (#1931)

🔐 New: Encryption Packages

Two new adapters let you encrypt values transparently. They share a wire format, so data written by one can be read by the other (same key + algorithm).

@keyv/encrypt-node — Node.js crypto

Supports AES-GCM (default), AES-CCM, ChaCha20-Poly1305, AES-CBC, and any cipher available in your Node install. (#1927)

import Keyv from 'keyv';
import KeyvEncryptNode from '@keyv/encrypt-node';

const encryption = new KeyvEncryptNode({ key: 'your-secret-key' });
const keyv = new Keyv({ encryption });

await keyv.set('foo', 'bar');
const value = await keyv.get('foo'); // 'bar' (decrypted automatically)
// Pick an algorithm and output encoding
const encryption = new KeyvEncryptNode({
  key: 'your-secret-key',
  algorithm: 'chacha20-poly1305',
  encoding: 'hex',
});

@keyv/encrypt-web — Web Crypto API

Works in browsers, Deno, Cloudflare Workers, and Node.js 18+ with no Node-specific dependencies. Supports AES-GCM (recommended) and AES-CBC. (#1928)

import Keyv from 'keyv';
import KeyvEncryptWeb from '@keyv/encrypt-web';

const encryption = new KeyvEncryptWeb({ key: 'your-secret-key' });
const keyv = new Keyv({ encryption });

await keyv.set('foo', 'bar');
const value = await keyv.get('foo'); // 'bar'

Cross-compatibility wire format (same for both packages):

  • AES-GCM: base64([IV (12 bytes) || AuthTag (16 bytes) || Ciphertext])
  • AES-CBC: base64([IV (16 bytes) || Ciphertext])

🧩 Core: Raw Data API

Work directly with the stored envelope ({ value, expires? }) — useful for replication, cache warming, and moving data between stores. (#1897, #1929)

import Keyv from 'keyv';
const keyv = new Keyv();

// Write a raw envelope with an absolute expiry timestamp
await keyv.setRaw('foo', { value: 'bar', expires: Date.now() + 60_000 });

// No expiry
await keyv.setRaw('foo', { value: 'bar' });

// Read the raw envelope back
const raw = await keyv.getRaw('foo'); // { value: 'bar', expires: 1234567890 }

// Copy between instances without unwrapping/rewrapping
if (raw) {
  await other.setRaw('foo', raw);
}

// Batch variants
await keyv.setManyRaw([
  { key: 'a', value: { value: 1 } },
  { key: 'b', value: { value: 2, expires: Date.now() + 60_000 } },
]);
const many = await keyv.getManyRaw(['a', 'b']);

The store-level TTL is derived automatically from value.expires, so you no longer pass a separate ttl to the raw setters.


🔎 Core: Capability Detection

New helpers report exactly which parts of an interface an object implements. Each returns a compatible flag — true only when the full interface is satisfied — plus a methods map describing whether each method exists and its methodType ("sync" / "async" / "none"). (#1909, #1930)

import Keyv, {
  detectKeyv,
  detectKeyvStorage,
  detectKeyvCompression,
  detectKeyvSerialization,
  detectKeyvEncryption,
} from 'keyv';

detectKeyv(new Keyv()).compatible; // true (only when ALL capabilities are present)
detectKeyv(new Map()).compatible;  // false — but methods.get.exists is still true

// Storage detection reports the detected store type plus sync/async per method
const r = detectKeyvStorage(new Map());
r.compatible;             // true
r.store;                  // "mapLike"  ("keyvStorage" | "mapLike" | "asyncMap" | "none")
r.methods.get.methodType; // "sync"

detectKeyvSerialization(JSON).compatible;                                    // true
detectKeyvCompression({ compress: d => d, decompress: d => d }).compatible;  // true
detectKeyvEncryption({ encrypt: d => d, decrypt: d => d }).compatible;       // true

📊 Core: Stats / Telemetry

Opt-in statistics with aggregate counters and LRU-bounded per-key frequency maps. (#1912)

const keyv = new Keyv({ stats: true });

await keyv.set('foo', 'bar');
await keyv.get('foo');          // hit
await keyv.get('nonexistent');  // miss
await keyv.delete('foo');

keyv.stats.hits;    // 1
keyv.stats.misses;  // 1
keyv.stats.sets;    // 1
keyv.stats.deletes; // 1

// Per-key frequency (each map capped at maxEntries, default 1000)
keyv.stats.hitKeys.get('foo');           // 1
keyv.stats.missKeys.get('nonexistent');  // 1

keyv.stats.reset();          // clears counters and maps
keyv.stats.enabled = false;  // disable at runtime (auto-unsubscribes)

🧼 Core: Key Sanitization

Opt-in detection that strips dangerous patterns (not harmless characters) from keys and namespaces — guarding against SQL injection, MongoDB operator injection, path traversal, and control-character/CRLF attacks. Results are LRU-cached for speed.

const keyv = new Keyv({ sanitize: true });
// or fine-grained:
const keyv2 = new Keyv({ sanitize: { sql: true, mongo: true, path: true, escape: true } });

Applied to every key-accepting method (get, set, delete, has, the *Many variants, and the raw variants), plus namespaces at construction and on the namespace setter.


🪝 Core: Events, Hooks & Error Handling

  • Hooks for more operations — added pre/post hooks for setMany, deleteMany, clear, and disconnect, in addition to the existing single-key hooks. (#1918, #1924)

  • throwOnErrors — make operations throw instead of emitting 'error', so you can try/catch (great with @keyv/redis connection handling). (#1910)

    import Keyv from 'keyv';
    import KeyvRedis from '@keyv/redis';
    
    const keyv = new Keyv({ store: new KeyvRedis('redis://localhost:6379'), throwOnErrors: true });
    try {
      await keyv.set('foo', 'bar');
    } catch (error) {
      // handle connection/timeout errors yourself
    }
  • Key prefixing moved to adapters. Prefixing/namespacing is now handled by the storage adapters that need it rather than the core. (#1899)

  • Encode/decode now propagate errors instead of swallowing ...

Read more

v6.0.0-beta.1

Choose a tag to compare

@jaredwray jaredwray released this 01 Apr 20:28

What's Changed

  • keyv - feat (breaking) stats / telemetry overhaul by @jaredwray in #1912
  • keyv - feat: (breaking) memory adapter, bridge adapter, keyv overhaul by @jaredwray in #1913
  • bigmap - feat: Optimize BigMap hash function and hot path performance by @jaredwray in #1915
  • dynamo - feat: Add disconnect and iterator methods to KeyvDynamo by @jaredwray in #1914
  • keyv - fix: handling has and hasMany better by @jaredwray in #1916
  • keyv - fix: adding in decode expiring to has by @jaredwray in #1917
  • keyv - feat: adding hooks for setMany and deleteMany by @jaredwray in #1918
  • keyv - fix: dead code on getManyRaw by @jaredwray in #1919
  • keyv - fix: on set with no result do not send telemetry STAT_SET by @jaredwray in #1920
  • keyv - fix: telemetry issue on setRaw by @jaredwray in #1921
  • keyv - fix: having encode / decode propegate errors by @jaredwray in #1922
  • keyv - feat: (breaking) by default keyv no longer checks expires by @jaredwray in #1923
  • keyv - feat: adding in hooks for clear and disconnect by @jaredwray in #1924
  • keyv - fix: minor bug fixes on memory, ttl, etc by @jaredwray in #1925
  • mono - feat: moving to tsdown for build by @jaredwray in #1926
  • encryption-node - feat: Add Node.js encryption adapter for Keyv by @jaredwray in #1927
  • encrypt-web - feat: adding new web crypto module by @jaredwray in #1928
  • keyv - feat: (breaking) removing StoredData and StoredDataRaw types by @jaredwray in #1929
  • keyv - feat: enhancing capabilities by @jaredwray in #1930
  • test-suite - feat (breaking) overhaul based on v6 changes by @jaredwray in #1931

Full Changelog: v6.0.0-alpha.4...v6.0.0-beta.1

v6.0.0-alpha.4

Choose a tag to compare

@jaredwray jaredwray released this 27 Mar 06:38

What's Changed

  • keyv - feat: (breaking) moving to Hookified by @jaredwray in #1900
  • compression - feat: moving to KeyvCompressionAdapter standard by @jaredwray in #1901
  • keyv - feat: (breaking) api changes and iterator simplification by @jaredwray in #1902
  • keyv - feat: moving storage setMany to use KeyvEntry by @jaredwray in #1903
  • keyv - feat: (breaking) moving to boolean return on set by @jaredwray in #1904
  • keyv - fix: (breaking) setRaw and setMany raw do not need ttl param by @jaredwray in #1905
  • keyv - feat: (breaking) removing opts from KeyvStorageAdapter by @jaredwray in #1906
  • keyv - feat: browser compatability by @jaredwray in #1907
  • keyv - fix: updating checks for browser tests by @jaredwray in #1908
  • feat: updating capability helper functions by @jaredwray in #1909
  • keyv - feat: clean up of code with fixes and helpers by @jaredwray in #1910

Full Changelog: v6.0.0-alpha.3...v6.0.0-alpha.4

v6.0.0-alpha.3

Choose a tag to compare

@jaredwray jaredwray released this 22 Mar 21:09

What's Changed

Full Changelog: v6.0.0-alpha.2...v6.0.0-alpha.3

v6.0.0-alpha.2

Choose a tag to compare

@jaredwray jaredwray released this 04 Mar 02:56

What's Changed

Full Changelog: 6.0.0-alpha.1...v6.0.0-alpha.2

6.0.0-alpha.1

Choose a tag to compare

@jaredwray jaredwray released this 26 Feb 01:35
d7419cf

What's Changed

  • redis - feat: exporting RedisSentinelOptions by @jaredwray in #1823
  • redis - feat: exporting redis sentinel options with updated documentation by @jaredwray in #1824
  • mono - chore: upgrading vitest to 4.0.18 by @jaredwray in #1827
  • keyv - chore: upgrading vitest and supporting modules to latest by @jaredwray in #1828
  • serialize - chore: upgrading vitest to 4.0.18 and supporting packages by @jaredwray in #1829
  • sqlite - feat: Add WAL (Write-Ahead Logging) mode support by @snomiao in #1826
  • compress-brotli - chore: upgrading vitest to 4.0.18 by @jaredwray in #1830
  • compress-gzip - chore: upgrading vitest to 4.0.18 by @jaredwray in #1831
  • sqlite - feat: Add warning for WAL mode with in-memory SQLite databases by @jaredwray in #1832
  • docs: Add v5 to v6 migration guide by @jaredwray in #1833
  • memcache - docs: Add memjs to memcache migration to v5-to-v6 guide by @jaredwray in #1836
  • mono - chore: moving keyv to better mono structure by @jaredwray in #1838
  • mono - feat: adding in version sync across all packages by @jaredwray in #1839
  • mono - fix: tsconfig moving to esnext by @jaredwray in #1840
  • compress-brotli - feat: moving to native zlib brotli engine by @jaredwray in #1841
  • mono - refactor: remove ttlSupport property from all storage adapters by @jaredwray in #1842
  • keyv - refactor: remove opts property from Keyv class by @jaredwray in #1843
  • keyv - chore: remove cyclic workspace dependencies by @jaredwray in #1844
  • keyv - chore: adding tests for code coverage by @jaredwray in #1845
  • memcache - feat: migrating from memjs to memcache by @jaredwray in #1846
  • memcache - feat: adding in createKeyv helper function by @jaredwray in #1847
  • memcache - fix: removing serialization as not needed by @jaredwray in #1848
  • memcache - feat: (breaking) moving to nodes based on memcache options by @jaredwray in #1849
  • memcache - feat: moving eventemitter to hookified by @jaredwray in #1850
  • memcache - feat: adding constructor documentation by @jaredwray in #1851
  • keyv - docs: Move Bun Support section lower in README by @jaredwray in #1853
  • postgres - feat: adding in table of contents by @jaredwray in #1856
  • postgres - feat: migrating to hookified and advanced functions by @jaredwray in #1857
  • postgres - feat: moving to properties by @jaredwray in #1858
  • postgres - feat: adding in native namespace support by @jaredwray in #1860
  • postgres - feat: better ttl support by @jaredwray in #1861
  • mysql - chore: adding table of contents by @jaredwray in #1862
  • mysql - feat: adding setMany and hasMany by @jaredwray in #1863
  • mysql - feat: moving to native namespacing by @jaredwray in #1864
  • mysql - feat: removing dialect as no longer needed by @jaredwray in #1865
  • mysql - feat: (breaking) moving from keySize to keyLength by @jaredwray in #1866
  • mysql - feat: moving from eventemitter to hookified by @jaredwray in #1867
  • mysql - feat: createKeyv helper and options cleanup by @jaredwray in #1868
  • mongo - feat: migrating to hookified from eventemitter by @jaredwray in #1869
  • mongo - feat: adding createKeyv helper by @jaredwray in #1871
  • mongo - feat: moving to more robust options and properties by @jaredwray in #1872
  • mongo - fix: moving gridFS property to read only by @jaredwray in #1873
  • mongo - feat: adding hasMany and setMany by @jaredwray in #1874
  • mono - feat: adding in release action by @jaredwray in #1875

New Contributors

Full Changelog: 2026-01-20...6.0.0-alpha.1

2026-01-20

Choose a tag to compare

@jaredwray jaredwray released this 21 Jan 00:37

What's Changed

Full Changelog: 2025-12-26...2025-01-20

2025-12-26

Choose a tag to compare

@jaredwray jaredwray released this 26 Dec 22:36

What's Changed

New Contributors

Full Changelog: 2025-12-10...2025-12-26