Quick Start
const redis = new Bun.RedisClient();
await redis.set("hello", "world");
const value = await redis.get("hello");
console.log(value); // "world"
await redis.close();
Creating a Client
Default Connection
// Connects to $VALKEY_URL, $REDIS_URL, or "valkey://localhost:6379"
const redis = new Bun.RedisClient();
Custom URL
const redis = new Bun.RedisClient("redis://localhost:6379");
// or
const redis = new Bun.RedisClient("valkey://localhost:6379");
With Options
const redis = new Bun.RedisClient("redis://localhost:6379", {
connectionTimeout: 5000, // ms
idleTimeout: 0, // No timeout
autoReconnect: true,
maxRetries: 10,
enableOfflineQueue: true,
enableAutoPipelining: true,
});
With TLS
const redis = new Bun.RedisClient("rediss://localhost:6380", {
tls: true,
// or with options
tls: {
ca: Bun.file("./ca.pem"),
cert: Bun.file("./cert.pem"),
key: Bun.file("./key.pem"),
},
});
Connection Management
Connect
const redis = new Bun.RedisClient();
// Explicit connect
await redis.connect();
// Or use callbacks
redis.onconnect = () => {
console.log("Connected to Redis");
};
redis.onclose = (error) => {
console.log("Disconnected:", error);
};
Close
redis.close();
Connection Status
if (redis.connected) {
console.log("Connected");
}
const buffered = redis.bufferedAmount;
console.log(`${buffered} bytes buffered`);
String Commands
GET and SET
await redis.set("key", "value");
const value = await redis.get("key");
console.log(value); // "value"
// Get as Buffer
const buffer = await redis.getBuffer("key");
SET with Options
// Expire in seconds
await redis.set("key", "value", "EX", 60);
// Expire in milliseconds
await redis.set("key", "value", "PX", 60000);
// Only if doesn't exist
await redis.set("key", "value", "NX");
// Only if exists
await redis.set("key", "value", "XX");
// Return old value
const old = await redis.set("key", "new", "GET");
// Keep TTL
await redis.set("key", "value", "KEEPTTL");
Increment/Decrement
await redis.set("counter", "0");
await redis.incr("counter"); // 1
await redis.incrby("counter", 5); // 6
await redis.decr("counter"); // 5
await redis.decrby("counter", 3); // 2
// Float increment
const result = await redis.incrbyfloat("price", 1.5);
console.log(result); // "1.5"
Other String Commands
// Append
await redis.append("key", " more");
// Get range
const substr = await redis.getrange("key", 0, 4);
// Set range
await redis.setrange("key", 6, "text");
// String length
const len = await redis.strlen("key");
// Get and delete
const value = await redis.getdel("key");
// Multiple get/set
await redis.mset(["key1", "val1", "key2", "val2"]);
const values = await redis.mget(["key1", "key2"]);
Key Commands
Existence and Deletion
// Check existence
if (await redis.exists("key")) {
console.log("Key exists");
}
// Delete keys
const deleted = await redis.del("key1", "key2");
console.log(`Deleted ${deleted} keys`);
// Unlink (async delete)
await redis.unlink("key1", "key2");
Expiration
// Expire in seconds
await redis.expire("key", 60);
// Expire at timestamp (seconds)
await redis.expireat("key", Date.now() / 1000 + 60);
// Expire in milliseconds
await redis.pexpire("key", 60000);
// Expire at timestamp (milliseconds)
await redis.pexpireat("key", Date.now() + 60000);
// Get TTL
const ttl = await redis.ttl("key"); // seconds
const pttl = await redis.pttl("key"); // milliseconds
// Remove expiration
await redis.persist("key");
Other Key Commands
// Rename
await redis.rename("oldkey", "newkey");
// Type
const type = await redis.type("key");
// Random key
const key = await redis.randomkey();
// Keys matching pattern
const keys = await redis.keys("user:*");
Hash Commands
// Set field
await redis.hset("user:1", "name", "Alice");
// Set multiple fields
await redis.hmset("user:1", { name: "Alice", email: "[email protected]" });
// Get field
const name = await redis.hget("user:1", "name");
// Get multiple fields
const fields = await redis.hmget("user:1", ["name", "email"]);
// Get all fields
const user = await redis.hgetall("user:1");
// Check field exists
if (await redis.hexists("user:1", "name")) {
console.log("Field exists");
}
// Delete fields
await redis.hdel("user:1", ["email"]);
// Get all keys/values
const keys = await redis.hkeys("user:1");
const values = await redis.hvals("user:1");
// Field count
const count = await redis.hlen("user:1");
// Increment field
await redis.hincrby("user:1", "visits", 1);
await redis.hincrbyfloat("user:1", "balance", 10.5);
List Commands
// Push
await redis.lpush("queue", "item1", "item2");
await redis.rpush("queue", "item3");
// Pop
const left = await redis.lpop("queue");
const right = await redis.rpop("queue");
// Blocking pop
const item = await redis.blpop(["queue"], 5); // timeout 5s
// Range
const items = await redis.lrange("queue", 0, -1);
// Length
const length = await redis.llen("queue");
// Index
const item = await redis.lindex("queue", 0);
// Set
await redis.lset("queue", 0, "new value");
// Trim
await redis.ltrim("queue", 0, 99);
Set Commands
// Add members
await redis.sadd("tags", "javascript", "typescript");
// Remove members
await redis.srem("tags", "typescript");
// Check membership
if (await redis.sismember("tags", "javascript")) {
console.log("Is member");
}
// Get all members
const members = await redis.smembers("tags");
// Cardinality
const count = await redis.scard("tags");
// Random member
const random = await redis.srandmember("tags");
// Pop random
const popped = await redis.spop("tags");
// Set operations
const union = await redis.sunion(["set1", "set2"]);
const inter = await redis.sinter(["set1", "set2"]);
const diff = await redis.sdiff(["set1", "set2"]);
Sorted Set Commands
// Add members with scores
await redis.zadd("leaderboard", 100, "alice");
await redis.zadd("leaderboard", 200, "bob");
// Get score
const score = await redis.zscore("leaderboard", "alice");
// Increment score
await redis.zincrby("leaderboard", 10, "alice");
// Range by rank
const top = await redis.zrange("leaderboard", 0, 9);
// Range by score
const range = await redis.zrangebyscore("leaderboard", 100, 200);
// Rank
const rank = await redis.zrank("leaderboard", "alice");
// Cardinality
const count = await redis.zcard("leaderboard");
// Remove
await redis.zrem("leaderboard", "alice");
Pub/Sub
// Subscribe to channels
await redis.subscribe("channel1");
// Publish message
await redis.publish("channel1", "Hello");
// Unsubscribe
await redis.unsubscribe("channel1");
// Pattern subscribe
await redis.psubscribe("news:*");
await redis.punsubscribe("news:*");
Transactions
Use pipelining for atomic operations:// Commands are automatically pipelined
const [result1, result2] = await Promise.all([
redis.set("key1", "value1"),
redis.set("key2", "value2"),
]);
Raw Commands
// Send custom command
const result = await redis.send("COMMAND", ["arg1", "arg2"]);
Type Signatures
class RedisClient {
constructor(url?: string, options?: RedisOptions);
connect(): Promise<void>;
close(): void;
readonly connected: boolean;
readonly bufferedAmount: number;
onconnect: ((this: RedisClient) => void) | null;
onclose: ((this: RedisClient, error: Error) => void) | null;
// String commands
get(key: string | ArrayBufferView | Blob): Promise<string | null>;
getBuffer(key: string | ArrayBufferView | Blob): Promise<Uint8Array | null>;
set(key: string | ArrayBufferView | Blob, value: string | ArrayBufferView | Blob): Promise<"OK">;
// Many more commands...
send(command: string, args: string[]): Promise<any>;
}
interface RedisOptions {
connectionTimeout?: number;
idleTimeout?: number;
autoReconnect?: boolean;
maxRetries?: number;
enableOfflineQueue?: boolean;
enableAutoPipelining?: boolean;
tls?: boolean | TLSOptions;
}