Type-safe Redis client for ReScript using Deno’s redis library.
Part of the ReScript Full Stack ecosystem.
rescript-redis provides comprehensive, type-safe bindings to Redis for ReScript applications running on Deno. It wraps the excellent deno.land/x/redis library with idiomatic ReScript APIs and proper option types.
-
Type Safety - Full ReScript type checking with proper
optiontypes for nullable responses -
Deno-First - Built for Deno, using native ES modules and Deno’s permissions model
-
Complete Coverage - Strings, Hashes, Lists, Sets, Sorted Sets, Pub/Sub, Streams, Sentinel, and Cluster
-
Zero Runtime Dependencies - Just ReScript and the Deno redis library
-
Ecosystem Integration - Works seamlessly with other rescript-full-stack packages
| Feature | Description |
|---|---|
Core Operations |
Strings, Hashes, Lists, Sets, Sorted Sets with full CRUD support |
Pub/Sub |
Subscribe to channels with async iteration support |
JSON Helpers |
|
Streams |
Full Redis Streams API with consumer groups (XADD, XREAD, XGROUP, etc.) |
Sentinel |
High availability with automatic failover support |
Cluster |
Horizontal scaling with Redis Cluster support |
Connection Management |
URL parsing, connection options, automatic reconnection |
// Connect to Redis
let redis = await Redis.make() // localhost:6379
// String operations
await redis->Redis.set("greeting", "Hello, ReScript!")
let greeting = await redis->Redis.get("greeting")
// greeting: option<string> = Some("Hello, ReScript!")
// With expiration (60 seconds)
await redis->Redis.setex("session", 60, "user123")
// Clean up
await redis->Redis.quit()// With explicit options
let redis = await Redis.connect({
hostname: "redis.example.com",
port: 6379,
password: "secret",
db: 1,
tls: true,
maxRetryCount: 5,
})
// From connection string
let redis = await Redis.makeFromUrl("redis://password@localhost:6379/0")// Store structured data
let user = {"id": 1, "name": "Alice", "active": true}->Obj.magic
await redis->Redis.setJson("user:1", user)
// Retrieve with automatic parsing
let retrieved = await redis->Redis.getJson("user:1")
// retrieved: option<JSON.t>
// With expiration
await redis->Redis.setJsonEx("cache:data", 300, someJsonValue)// Set hash fields
await redis->Redis.hset("user:1", "name", "Alice")
await redis->Redis.hset("user:1", "email", "alice@example.com")
// Get a field
let name = await redis->Redis.hget("user:1", "name")
// Get all fields as dictionary
let user = await redis->Redis.hgetallAsDict("user:1")
// user: Dict.t<string>
// Atomic increment
await redis->Redis.hincrby("user:1", "visits", 1)// Push to list
await redis->Redis.lpush("queue", ["job1", "job2", "job3"])
// Pop from list
let job = await redis->Redis.rpop("queue")
// Get range
let items = await redis->Redis.lrange("queue", 0, -1)// Add members
await redis->Redis.sadd("tags", ["rescript", "redis", "deno"])
// Check membership
let isMember = await redis->Redis.sismember("tags", "rescript")
// Get all members
let tags = await redis->Redis.smembers("tags")// Subscriber
let sub = await Redis.make()
let subscription = await sub->Redis.subscribe(["events", "notifications"])
// Async iteration over messages
let iterator = subscription->Redis.receive()
// Use with for-await or manual iteration
// Publisher (separate connection)
let pub = await Redis.make()
await pub->Redis.publish("events", "user.created")Streams provide a log-like data structure for event sourcing and message queues.
open Redis.Streams
// Add entries
let id = await redis->add("events", Dict.fromArray([
("type", "user.created"),
("userId", "123"),
]))
// Read all entries
let entries = await redis->rangeAll("events")
entries->Array.forEach(entry => {
Console.log2("ID:", entry.id)
Console.log2("Fields:", entry.fields)
})
// Read range
let recent = await redis->range("events", "-", "+")open Redis.Streams
// Create consumer group
await redis->groupCreateFromEnd("events", "processors")
// Read as consumer
let messages = await redis->readGroupNew(
"processors", // group name
"worker-1", // consumer name
"events" // stream name
)
// Process and acknowledge
switch messages {
| Some(entries) =>
let ids = entries->Array.map(e => e.id)
await redis->ack("events", "processors", ids)
| None => ()
}open Redis.Sentinel
let redis = await make({
masterName: "mymaster",
sentinels: [
{hostname: "sentinel1.example.com", port: 26379},
{hostname: "sentinel2.example.com", port: 26379},
{hostname: "sentinel3.example.com", port: 26379},
],
password: "secret",
})
// Use redis normally - failover is automatic
await redis->Redis.set("key", "value")open Redis.Cluster
let redis = await make({
nodes: [
{hostname: "redis1.example.com", port: 6379},
{hostname: "redis2.example.com", port: 6379},
{hostname: "redis3.example.com", port: 6379},
],
password: "secret",
maxRedirections: 16,
})
// Cluster operations
let healthy = await redis->isHealthy()
// Use redis normally - routing is automatic
await redis->Redis.set("key", "value")| Function | Description | Returns |
|---|---|---|
|
Connect with explicit options |
|
|
Connect to localhost:6379 |
|
|
Connect using connection string |
|
|
Ping the server |
|
|
Gracefully close connection |
|
|
Immediately close connection |
|
| Function | Description | Returns |
|---|---|---|
|
Get value |
|
|
Set value |
|
|
Set with expiration |
|
|
Set if not exists |
|
|
Delete keys |
|
|
Check existence |
|
|
Set TTL |
|
|
Get TTL |
|
|
Increment by 1 |
|
|
Increment by n |
|
|
Decrement by 1 |
|
|
Decrement by n |
|
| Function | Description | Returns |
|---|---|---|
|
Get field value |
|
|
Set field value |
|
|
Delete fields |
|
|
Get all (flat array) |
|
|
Get all (dictionary) |
|
|
Check field exists |
|
|
Increment field |
|
|
Get field names |
|
|
Get all values |
|
|
Count fields |
|
| Function | Description | Returns |
|---|---|---|
|
Prepend values |
|
|
Append values |
|
|
Pop from head |
|
|
Pop from tail |
|
|
Get range |
|
|
Get length |
|
|
Get by index |
|
|
Set by index |
|
| Function | Description | Returns |
|---|---|---|
|
Add members |
|
|
Remove members |
|
|
Get all members |
|
|
Check membership |
|
|
Get cardinality |
|
| Function | Description | Returns |
|---|---|---|
|
Add with score |
|
|
Remove members |
|
|
Get score |
|
|
Get rank (low to high) |
|
|
Get range (ascending) |
|
|
Get range (descending) |
|
|
Get cardinality |
|
-
Redis 7.x (for testing)
# Install dependencies and build
deno task build
# Watch mode
deno task dev
# Clean build artifacts
deno task clean# Run tests (requires Redis on localhost:6379)
deno task test
# Watch mode
deno task test:watchThe ReScript Full Stack ecosystem includes:
-
rescript-effect - Effect system
-
rescript-schema - Runtime validation
-
rescript-webapi - Web API bindings
-
rescript-fetch - HTTP client
See CONTRIBUTING.adoc for guidelines.
See CHANGELOG.adoc for version history.
PMPL-1.0-or-later. See LICENSE.txt for details.
Copyright © 2025 Hyperpolymath