redis

Redis client for Kit using native Zig FFI

Files

FileDescription
.editorconfigEditor formatting configuration
.gitignoreGit ignore rules for build artifacts and dependencies
.tool-versionsasdf tool versions (Zig, Kit)
LICENSEMIT license file
README.mdThis file
examples/basic.kitBasic Redis connection, string, and counter example
examples/live-smoke.kitLive Redis smoke check with environment-based configuration
examples/redis.kitBroad example covering the currently exported Redis API
kit.tomlPackage manifest with metadata, capabilities, tasks, and dependencies
src/redis.kitKit API surface, typed errors, Redis reply types, and extern-zig bindings
tests/redis.test.kitKit tests for exported types and functions
zig/kit_ffi.zigZig definitions for the Kit FFI value ABI
zig/redis.zigNative Redis client implementation, RESP parser, sockets, TLS, and FFI exports

Dependencies

No Kit package dependencies.

This package requires the ffi and tcp capabilities at runtime.

For live examples, run a Redis server that is reachable from the Kit process. The examples default to 127.0.0.1:6379.

Installation

kit add gitlab.com/kit-lang/packages/kit-redis.git

Usage

import Kit.Redis as Redis

main = fn =>
  match Redis.connect "127.0.0.1" 6379
    | Err err ->
      println "Failed to connect: ${err}"

    | Ok conn ->
      defer Redis.close conn

      match Redis.ping conn
        | Ok pong -> println "PING: ${pong}"
        | Err err -> println "PING failed: ${err}"

      match Redis.set conn "greeting" "Hello from kit-redis!"
        | Ok _ -> println "SET greeting succeeded"
        | Err err -> println "SET failed: ${err}"

      match Redis.get conn "greeting"
        | Ok (Some value) -> println "GET greeting: ${value}"
        | Ok None -> println "GET greeting: (nil)"
        | Err err -> println "GET failed: ${err}"

      Redis.del conn "counter" |> Result.unwrap
      match Redis.incr conn "counter"
        | Ok n -> println "INCR counter: ${n}"
        | Err err -> println "INCR failed: ${err}"

      Redis.del conn "greeting" |> Result.unwrap
      Redis.del conn "counter" |> Result.unwrap

main

API Overview

kit-redis currently supports:

  • connection: connect, connect-timeout, connect-unix, connect-url, connect-url-timeout, close, ping, auth, auth-user, select-db
  • transactions: watch, unwatch, multi, exec, discard
  • strings and keys: get, getdel, getex, getpex, getset, getrange, mget, set, mset, msetnx, setex, append, strlen, setrange, psetex, setnx, setnxex, setnxpx, del, unlink, del-many, unlink-many, rename, renamenx, exists?, exists-many, expire, expireat, pexpire, pexpireat, persist, touch, ttl, pttl, key-type, scan, dbsize, flushdb
  • counters: incr, decr, incrby, incrbyfloat, decrby
  • lists: lpush, rpush, llen, lrange, lindex, lset, ltrim, lpos, lrem, rpoplpush, lpop, rpop
  • sorted sets: zadd, zincrby, zrem, zcard, zrank, zrevrank, zscore, zmscore, zcount, zlexcount, zunionstore, zunion, zinterstore, zinter, zdiff, zdiffstore, zremrangebyrank, zremrangebyscore, zremrangebylex, zrange, zrevrange, zrange-withscores, zrangebylex, zrevrangebylex, zrangebyscore, zrevrangebyscore, zpopmin, zpopmax, zrandmember, zscan
  • sets: sadd, srem, smove, smembers, sismember?, scard, sunionstore, sunion, sinterstore, sinter, sdiff, sdiffstore, spop, srandmember, sscan
  • hashes: hset, hsetnx, hset-many, hget, hmget, hincrby, hincrbyfloat, hdel, hdel-many, hexists?, hgetall, hkeys, hvals, hlen, hstrlen, hscan
  • generic commands: command

All exported operations return Result values. Connection failures use RedisConnectionError; Redis command failures use RedisCommandError.

Generic Commands

command is the escape hatch for Redis commands that do not have a dedicated typed wrapper yet:

match Redis.command conn ["PING"]
  | Ok (RedisSimpleString "PONG") -> println "pong"
  | Ok reply -> println "unexpected reply: ${show reply}"
  | Err err -> println "command failed: ${err}"

The returned RedisReply variants mirror RESP reply shapes:

  • RedisSimpleString String
  • RedisErrorString String
  • RedisInteger Int
  • RedisBulkString String
  • RedisNullBulkString
  • RedisArray [RedisReply]
  • RedisNullArray

Development

Running Examples

Run the basic example with the interpreter:

kit run examples/basic.kit --allow=ffi,tcp

Run the live smoke example:

kit run examples/live-smoke.kit --allow=ffi,tcp

Compile an example to a native binary:

kit build examples/basic.kit && ./basic

Live Redis Configuration

examples/live-smoke.kit reads these optional environment variables:

  • KIT_REDIS_HOST defaults to 127.0.0.1
  • KIT_REDIS_PORT defaults to 6379
  • KIT_REDIS_DB defaults to 9
  • KIT_REDIS_USERNAME enables ACL-style authentication
  • KIT_REDIS_PASSWORD enables an authenticated smoke flow against password-protected Redis

Running Tests

Run the Kit test suite:

kit test

Run the Zig test suite:

zig test zig/redis.zig

Run the test suite with coverage:

kit test --coverage

Running kit dev

Run the standard development workflow (format, check, test):

kit dev

This will:

  1. Format and check source files in src/
  2. Type check examples in examples/
  3. Run tests in tests/ with coverage

Running Parity

Compare interpreter and native output for all examples:

kit parity --failures-only

Parity expects a reachable Redis server for the live examples.

Generating Documentation

Generate API documentation from doc comments:

kit doc

Note: Kit sources with doc comments (##) generate HTML documents in docs/*.html.

Cleaning Build Artifacts

Remove generated files, caches, parity results, coverage data, and build artifacts:

kit task clean

Note: Defined in kit.toml.

Developer Notes

  • connect-url supports redis:// and rediss:// URLs with embedded credentials and /db paths, such as redis://:secret@localhost:6379/2, redis://kit-user:secret@localhost:6379/0, or rediss://cache.example.com:6380/0.
  • rediss:// uses Zig's TLS client with system CA verification. The default TLS port is 6380.
  • connect-unix supports Redis deployments exposed through a Unix domain socket path.
  • connect-timeout and connect-url-timeout perform timed TCP connects in milliseconds.
  • auth-user supports Redis ACL authentication for host/port and Unix-socket connections without requiring a URL.
  • ttl and pttl return Redis sentinel values unchanged: -1 means the key has no expiry and -2 means the key does not exist.
  • getex, getpex, getdel, getset, setnxex, and setnxpx expose atomic Redis primitives that are safer than composing separate read, write, and expiry operations in Kit code.
  • mget, hmget, and batch delete/write helpers preserve order and use Option String where Redis can return missing values.
  • scan, sscan, hscan, and zscan return cursor records so larger datasets can be traversed incrementally.
  • command is intended as an escape hatch; prefer dedicated typed helpers where they exist.
  • Native Redis handles are represented as Int values in Kit and must be closed with close. The connection helpers are annotated so Kit diagnostics can require defer Redis.close conn-style cleanup.

Local Installation

To install this package locally for development:

kit install

This installs the package to ~/.kit/packages/@kit/redis/, making it available for import as Kit.Redis in other projects.

License

This package is released under the MIT License - see LICENSE for details.

Exported Functions & Types

RedisError

Redis error type for typed error handling. Variants distinguish between connection and command errors.

Variants

RedisConnectionError {message}
RedisCommandError {message}

RedisReply

Generic RESP reply type for the command escape hatch.

Variants

RedisSimpleString {String}
RedisErrorString {String}
RedisInteger {Int}
RedisBulkString {String}
RedisNullBulkString
RedisArray {_0}
RedisNullArray

connect

Connect to a Redis server at the specified host and port.

String -> Int -> Result Int RedisError

connect-timeout

Connect to a Redis server with a connection timeout in milliseconds.

String -> Int -> Int -> Result Int RedisError

connect-unix

Connect to a Redis server via Unix domain socket.

String -> Result Int RedisError

connect-url

Connect to a Redis server using a URL.

String -> Result Int RedisError

connect-url-timeout

Connect to a Redis server using a URL with a connection timeout in milliseconds.

String -> Int -> Result Int RedisError

close

Close a Redis connection and free associated resources.

Int -> Result Unit RedisError

ping

Send a PING command to test the connection.

Int -> Result String RedisError

auth

Authenticate with the Redis server using a password.

Int -> String -> Result Unit RedisError

auth-user

Authenticate with the Redis server using ACL username and password.

Int -> String -> String -> Result Unit RedisError

select-db

Select a Redis database by index.

Int -> Int -> Result Unit RedisError

watch

Watch one or more keys for changes before a later transaction.

Int -> [String] -> Result Unit RedisError

unwatch

Clear all watched keys on the current connection.

Int -> Result Unit RedisError

multi

Start a Redis transaction block on the current connection.

Int -> Result Unit RedisError

exec

Execute the queued commands in the current transaction.

Int -> Result RedisReply RedisError

discard

Discard the queued commands in the current transaction.

Int -> Result Unit RedisError

get

Get the value of a key.

Int -> String -> Result (Option String) RedisError

getdel

Get the value of a key and delete it atomically.

Int -> String -> Result (Option String) RedisError

getex

Get the value of a key and reset its expiration in seconds atomically.

Int -> String -> Int -> Result (Option String) RedisError

getpex

Get the value of a key and reset its expiration in milliseconds atomically.

Int -> String -> Int -> Result (Option String) RedisError

getset

Set the value of a key and return its previous value atomically.

Int -> String -> String -> Result (Option String) RedisError

getrange

Get a substring of a string value using inclusive start and stop offsets.

Int -> String -> Int -> Int -> Result String RedisError

mget

Get multiple values in a single Redis command.

Int -> [String] -> Result [(Option String)] RedisError

set

Set the value of a key.

Int -> String -> String -> Result Unit RedisError

mset

Set multiple key/value pairs in a single Redis command.

Int -> [RedisItem] -> Result Unit RedisError

msetnx

Set multiple key/value pairs only if none of the keys already exist.

Int -> [RedisItem] -> Result Bool RedisError

setex

Set the value of a key with expiration in seconds.

Int -> String -> Int -> String -> Result Unit RedisError

append

Append text to the existing string value at a key.

Int -> String -> String -> Result Int RedisError

strlen

Get the length of a string value in bytes.

Int -> String -> Result Int RedisError

setrange

Overwrite part of a string value starting at the given byte offset.

Int -> String -> Int -> String -> Result Int RedisError

psetex

Set the value of a key with expiration in milliseconds.

Int -> String -> Int -> String -> Result Unit RedisError

setnx

Set the value of a key only if it does not already exist.

Int -> String -> String -> Result Bool RedisError

setnxex

Atomically set the value of a key with expiration in seconds only if it does not already exist.

Int -> String -> Int -> String -> Result Bool RedisError

setnxpx

Atomically set the value of a key with expiration in milliseconds only if it does not already exist.

Int -> String -> Int -> String -> Result Bool RedisError

del

Delete a key.

Int -> String -> Result Int RedisError

Asynchronously delete a key.

Int -> String -> Result Int RedisError

del-many

Delete multiple keys in a single Redis command.

Int -> [String] -> Result Int RedisError

Asynchronously delete multiple keys in a single Redis command.

Int -> [String] -> Result Int RedisError

rename

Rename a key atomically, overwriting the destination if it exists.

Int -> String -> String -> Result Unit RedisError

renamenx

Rename a key only if the destination does not already exist.

Int -> String -> String -> Result Bool RedisError

exists-many

Count how many of the given keys currently exist.

Int -> [String] -> Result Int RedisError

key-type

Get the Redis type of a key.

Int -> String -> Result String RedisError

expire

Set an expiration on a key in seconds.

Int -> String -> Int -> Result Bool RedisError

expireat

Set an absolute expiration timestamp on a key in seconds since the Unix epoch.

Int -> String -> Int -> Result Bool RedisError

pexpire

Set an expiration on a key in milliseconds.

Int -> String -> Int -> Result Bool RedisError

pexpireat

Set an absolute expiration timestamp on a key in milliseconds since the Unix epoch.

Int -> String -> Int -> Result Bool RedisError

persist

Remove the expiration from a key.

Int -> String -> Result Bool RedisError

touch

Update the last access time of a key without rewriting its value.

Int -> String -> Result Bool RedisError

ttl

Get the remaining time to live of a key.

Int -> String -> Result Int RedisError

pttl

Get the remaining time to live of a key in milliseconds.

Int -> String -> Result Int RedisError

incr

Increment the integer value of a key by 1.

Int -> String -> Result Int RedisError

decr

Decrement the integer value of a key by 1.

Int -> String -> Result Int RedisError

incrby

Increment the integer value of a key by the provided amount.

Int -> String -> Int -> Result Int RedisError

incrbyfloat

Increment the floating-point value of a key by the provided amount.

Int -> String -> Float -> Result Float RedisError

decrby

Decrement the integer value of a key by the provided amount.

Int -> String -> Int -> Result Int RedisError

lpush

Push a value to the head (left) of a list.

Int -> String -> String -> Result Int RedisError

rpush

Push a value to the tail (right) of a list.

Int -> String -> String -> Result Int RedisError

llen

Get the length of a list.

Int -> String -> Result Int RedisError

lrange

Get a range of values from a list.

Int -> String -> Int -> Int -> Result [String] RedisError

lindex

Get a single value from a list by index.

Int -> String -> Int -> Result (Option String) RedisError

lset

Replace a list value at an index.

Int -> String -> Int -> String -> Result Unit RedisError

ltrim

Trim a list to the inclusive index range.

Int -> String -> Int -> Int -> Result Unit RedisError

lpos

Find the first index of a list value.

Int -> String -> String -> Result (Option Int) RedisError

lrem

Remove list elements equal to the given value.

Int -> String -> Int -> String -> Result Int RedisError

rpoplpush

Pop a value from the tail of one list and push it onto the head of another list atomically.

Int -> String -> String -> Result (Option String) RedisError

lpop

Pop a value from the head (left) of a list.

Int -> String -> Result (Option String) RedisError

rpop

Pop a value from the tail (right) of a list.

Int -> String -> Result (Option String) RedisError

zadd

Add a member to a sorted set with the given score.

Int -> String -> Float -> String -> Result Bool RedisError

zincrby

Increment the score of a sorted set member.

Int -> String -> Float -> String -> Result Float RedisError

zrem

Remove a member from a sorted set.

Int -> String -> String -> Result Bool RedisError

zcard

Get the number of members in a sorted set.

Int -> String -> Result Int RedisError

zrank

Get the zero-based rank of a sorted set member in ascending score order.

Int -> String -> String -> Result (Option Int) RedisError

zrevrank

Get the zero-based rank of a sorted set member in descending score order.

Int -> String -> String -> Result (Option Int) RedisError

zscore

Get the score of a sorted set member.

Int -> String -> String -> Result (Option Float) RedisError

zmscore

Get the scores of multiple sorted set members in one Redis command.

Int -> String -> [String] -> Result [(Option Float)] RedisError

zcount

Count how many sorted set members have scores within the inclusive score range.

Int -> String -> Float -> Float -> Result Int RedisError

zlexcount

Count how many sorted set members fall within the inclusive lexicographical range.

Int -> String -> String -> String -> Result Int RedisError

zunionstore

Store the union of multiple sorted sets in a destination sorted set.

Int -> String -> [String] -> Result Int RedisError

zunion

Return the union of multiple sorted sets as member names.

Int -> [String] -> Result [String] RedisError

zinterstore

Store the intersection of multiple sorted sets in a destination sorted set.

Int -> String -> [String] -> Result Int RedisError

zinter

Return the intersection of multiple sorted sets as member names.

Int -> [String] -> Result [String] RedisError

zdiff

Return the difference of multiple sorted sets as member names.

Int -> [String] -> Result [String] RedisError

zdiffstore

Store the difference of multiple sorted sets in a destination sorted set.

Int -> String -> [String] -> Result Int RedisError

zremrangebyrank

Remove sorted set members whose ranks fall within the inclusive rank range.

Int -> String -> Int -> Int -> Result Int RedisError

zremrangebyscore

Remove sorted set members whose scores fall within the inclusive score range.

Int -> String -> Float -> Float -> Result Int RedisError

zremrangebylex

Remove sorted set members whose values fall within the inclusive lexicographical range.

Int -> String -> String -> String -> Result Int RedisError

zrange

Get a range of members from a sorted set by index.

Int -> String -> Int -> Int -> Result [String] RedisError

zrevrange

Get a range of members from a sorted set by index in descending score order.

Int -> String -> Int -> Int -> Result [String] RedisError

zrange-withscores

Get a range of sorted set members with their scores by index.

Int -> String -> Int -> Int -> Result [RedisSortedSetItem] RedisError

zrangebylex

Get sorted set members whose values fall within the inclusive lexicographical range.

Int -> String -> String -> String -> Result [String] RedisError

zrevrangebylex

Get sorted set members whose values fall within the inclusive lexicographical range in descending order.

Int -> String -> String -> String -> Result [String] RedisError

zrangebyscore

Get sorted set members whose scores fall within the inclusive score range.

Int -> String -> Float -> Float -> Result [String] RedisError

zrevrangebyscore

Get sorted set members whose scores fall within the inclusive score range in descending order.

Int -> String -> Float -> Float -> Result [String] RedisError

zpopmin

Pop and return the member with the lowest score from a sorted set.

Int -> String -> Result (Option RedisSortedSetItem) RedisError

zpopmax

Pop and return the member with the highest score from a sorted set.

Int -> String -> Result (Option RedisSortedSetItem) RedisError

zrandmember

Return a random member from a sorted set without removing it.

Int -> String -> Result (Option String) RedisError

zscan

Incrementally scan a sorted set.

Int -> String -> Int -> String -> Int -> Result {cursor: Int, items: [RedisSortedSetItem]} RedisError

sadd

Add a member to a set.

Int -> String -> String -> Result Bool RedisError

srem

Remove a member from a set.

Int -> String -> String -> Result Bool RedisError

smove

Move a member atomically from one set to another.

Int -> String -> String -> String -> Result Bool RedisError

smembers

Get all members from a set.

Int -> String -> Result [String] RedisError

scard

Get the number of members in a set.

Int -> String -> Result Int RedisError

sunionstore

Store the union of multiple sets in a destination set.

Int -> String -> [String] -> Result Int RedisError

sunion

Return the union of multiple sets as member names.

Int -> [String] -> Result [String] RedisError

sinterstore

Store the intersection of multiple sets in a destination set.

Int -> String -> [String] -> Result Int RedisError

sinter

Return the intersection of multiple sets as member names.

Int -> [String] -> Result [String] RedisError

sdiff

Return the difference of multiple sets as member names.

Int -> [String] -> Result [String] RedisError

sdiffstore

Store the difference of multiple sets in a destination set.

Int -> String -> [String] -> Result Int RedisError

spop

Pop and return a random member from a set.

Int -> String -> Result (Option String) RedisError

srandmember

Return a random member from a set without removing it.

Int -> String -> Result (Option String) RedisError

sscan

Incrementally scan set members using a cursor, pattern, and count hint.

Int -> String -> Int -> String -> Int -> Result {cursor: Int, members: [String]} RedisError

hset

Set a field in a hash.

Int -> String -> String -> String -> Result Bool RedisError

hsetnx

Set a field in a hash only if it does not already exist.

Int -> String -> String -> String -> Result Bool RedisError

hget

Get the value of a hash field.

Int -> String -> String -> Result (Option String) RedisError

hincrby

Increment an integer hash field by the provided amount.

Int -> String -> String -> Int -> Result Int RedisError

hincrbyfloat

Increment a floating-point hash field by the provided amount.

Int -> String -> String -> Float -> Result Float RedisError

hset-many

Set multiple hash fields in a single Redis command.

Int -> String -> [RedisHashItem] -> Result Int RedisError

hmget

Get the values of multiple hash fields.

Int -> String -> [String] -> Result [(Option String)] RedisError

hdel

Delete a field from a hash.

Int -> String -> String -> Result Int RedisError

hdel-many

Delete multiple fields from a hash in a single Redis command.

Int -> String -> [String] -> Result Int RedisError

hgetall

Get all fields and values from a hash.

Int -> String -> Result [RedisHashItem] RedisError

hkeys

Get all field names from a hash.

Int -> String -> Result [String] RedisError

hvals

Get all values from a hash.

Int -> String -> Result [String] RedisError

hlen

Get the number of fields in a hash.

Int -> String -> Result Int RedisError

hstrlen

Get the string length of a hash field value.

Int -> String -> String -> Result Int RedisError

hscan

Incrementally scan hash fields and values using a cursor, pattern, and count hint.

Int -> String -> Int -> String -> Int -> Result {cursor: Int, items: [RedisHashItem]} RedisError

command

Execute an arbitrary Redis command expressed as command parts.

Int -> [String] -> Result RedisReply RedisError

scan

Incrementally scan keys using a cursor, pattern, and count hint.

Int -> Int -> String -> Int -> Result {cursor: Int, keys: [String]} RedisError

dbsize

Get the number of keys in the selected database.

Int -> Result Int RedisError

flushdb

Remove all keys from the selected database.

Int -> Result Unit RedisError