Key-value storage
Read and write data in Cloudflare Workers KV with kv from void/kv. Values are stored as JSON, and kv.map() gives a collection its own key prefix and value type.
On this pageGet, put, delete and list keys · Store typed collections with kv.map() · Read metadata
Basic operations
These examples read, write, delete and list keys.
Get
import { kv } from 'void/kv';
const user = await kv.get<User>('user:123');
// User | nullValues are parsed as JSON. If a value is not valid JSON, you get the raw string.
Put
await kv.put('user:123', { name: 'Alice', role: 'admin' });All values are stored as JSON, strings included. Reads keep the type, so "123" or "null" comes back as a string.
This step sets a TTL in seconds, or an absolute expiry as a Unix timestamp.
await kv.put('session:abc', sessionData, { ttl: 3600 });
await kv.put('token:xyz', tokenData, { expiration: 1700000000 });This step attaches metadata to a key.
await kv.put('user:123', userData, {
metadata: { updatedBy: 'admin' },
});Delete
await kv.delete('user:123');List
const result = await kv.list({ prefix: 'user:' });
// { keys: [{ name: "user:1" }, { name: "user:2" }], list_complete: true }This step pages through keys with limit and cursor.
const page = await kv.list({ prefix: 'user:', limit: 100 });
if (!page.list_complete) {
const next = await kv.list({ prefix: 'user:', limit: 100, cursor: page.cursor });
}Get with metadata
const result = await kv.getWithMetadata<User, { updatedBy: string }>('user:123');
// { value: User | null, metadata: { updatedBy: string } | null }Typed maps
This step creates a typed client for one collection. kv.map() scopes it with a key prefix.
const sessions = kv.map<Session>('sessions');
await sessions.put('abc', { userId: 1, token: '...' }, { ttl: 3600 });
// KV key: "sessions:abc"
const session = await sessions.get('abc');
// Session | null
await sessions.delete('abc');The map adds the "sessions:" prefix to every key. It strips the prefix when listing.
const result = await sessions.list();
// keys: [{ name: "abc" }, { name: "def" }] (prefix stripped)Maps have the base client's methods: get, put, delete, list and getWithMetadata. Values are typed and keys are prefixed.
For anything else, use the raw KVNamespace at c.env.KV in a route handler.