keyscope_client

Keyscope Logo

The ultimate multi-engine client for Redis, Valkey, and Dragonfly.

A high-performance, cluster-aware SDK with seamless polymorphic aliases. Switch identities seamlessly with built-in polymorphic aliases.

pub package CT pub package

Supported CommandsUsageFeaturesWhy keyscope_client?

Supported Commands

Not just basic strings. Our goal is to provide a 100% complete command experience across all data types in the Dart/Flutter ecosystem.

Core Data Types

Basic data structures and generic key operations.

Modules & Extensions

Advanced data types and query engines (JSON, Search, Probabilistic structures).

System & Operations

Server management, connection handling, and flow control.

Usage

KeyscopeClient provides a unified API with full alias sets for Redis, Valkey, and Dragonfly (including Client, ClusterClient, Pool, Exceptions, Configuration, and Data Models). Whether you prefer engine-specific naming or a unified approach, we've got you covered. (Check out Developer Experience Improvements).

1-1. Redis, Valkey, and Dragonfly Standalone (Basic)

For Redis users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final client = RedisClient(
    host: 'localhost', 
    port: 6379, 
    // password: '',
  );
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Redis!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Valkey users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final client = ValkeyClient(
    host: 'localhost', 
    port: 6379, 
    // password: '',
  );
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Valkey!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Dragonfly users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final client = DragonflyClient(
    host: 'localhost', 
    port: 6379, 
    // password: '',
  );
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Dragonfly!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

1-2. Redis, Valkey, and Dragonfly Standalone (Advanced)

For Redis users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = RedisConnectionSettings(
    host: 'localhost',
    port: 6379,
    // useSsl: false,
    // database: 0,
  );
  final client = RedisClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Redis!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Valkey users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = ValkeyConnectionSettings(
    host: 'localhost',
    port: 6379,
    // useSsl: false,
    // database: 0,
  );
  final client = ValkeyClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Valkey!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Dragonfly users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = DragonflyConnectionSettings(
    host: 'localhost',
    port: 6379,
    // useSsl: false,
    // database: 0,
  );
  final client = DragonflyClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Dragonfly!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

2. Redis, Valkey, and Dragonfly Sentinel

For Redis users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = RedisConnectionSettings(
    host: 'localhost',
    port: 6379,
    readPreference: ReadPreference.preferReplica
  );
  final client = RedisClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Redis!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Valkey users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = ValkeyConnectionSettings(
    host: 'localhost',
    port: 6379,
    readPreference: ReadPreference.preferReplica
  );
  final client = ValkeyClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Valkey!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Dragonfly users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final settings = DragonflyConnectionSettings(
    host: 'localhost',
    port: 6379,
    readPreference: ReadPreference.preferReplica
  );
  final client = DragonflyClient.fromSettings(settings);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Dragonfly!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

3. Redis, Valkey, and Dragonfly Cluster

For Redis users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final nodes = [
    RedisConnectionSettings(
      host: 'localhost', 
      port: 7001,
    )
  ];
  final client = RedisClusterClient(nodes);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Redis!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Valkey users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final nodes = [
    ValkeyConnectionSettings(
      host: 'localhost', 
      port: 7001,
    )
  ];
  final client = ValkeyClusterClient(nodes);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Valkey!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

For Dragonfly users

import 'package:keyscope_client/keyscope_client.dart';

void main() async {
  final nodes = [
    DragonflyConnectionSettings(
      host: 'localhost', 
      port: 7001,
    )
  ];
  final client = DragonflyClusterClient(nodes);
  try {
    await client.connect();
    await client.set('Hello', 'Welcome to Dragonfly!');
    print(await client.get('Hello'));
  } catch (e) {
    print('Error: $e');
  } finally {
    await client.close();
  }
}

Features

🚀 Performance & Scalability

Feature Description
Scalable Replica Reads Boost read performance by offloading read-only commands (e.g., GET, EXISTS)
to replica nodes. Supports ReadPreference settings (master, preferReplica, replicaOnly) to control traffic flow.
Smart Load Balancing Built-in load balancing strategies (Round-Robin, Random) to efficiently distribute read traffic across available replicas.
Multi-key Support Supports MGET across multiple nodes using smart Scatter-Gather pipelining.
Sharded Pub/Sub & Atomic Counters Added support for high-performance cluster messaging (SPUBLISH/SSUBSCRIBE) and atomic integer operations (INCR/DECR).

🛡️ High Availability & Resilience

Feature Description
Automatic Failover Resilience: The client now survives node failures. If a master node goes down
(connection refused/timeout), the client automatically refreshes the
cluster topology and reroutes commands to the new master without throwing an exception.
High Availability & Resilience Automatically and transparently handles cluster topology changes
(-MOVED and -ASK redirections) to ensure robust failover, seamless scaling, and zero‑downtime operations.
Automatic Replica Discovery Automatically detects and connects to replica nodes via
INFO REPLICATION (Standalone/Sentinel) to maintain an up-to-date pool of connections.
Cluster Auto-Discovery Added client.clusterSlots() to fetch cluster topology
(via the CLUSTER SLOTS command), laying the foundation for full cluster support.

🧩 Developer Experience & Tooling

Feature Description
Redis/Valkey Module Detector Retrieves module metadata to identify installed extensions
(e.g., json, search, ldap, bf).
JSON Module Checker Pre-validates JSON module availability before execution.
Server Metadata Discovery Access server details via client.metadata (Version, Mode, Server Name,
Max Databases) to write adaptive logic for Valkey vs. Redis.
Enhanced Developer Experience Provides full alias sets for Redis and Valkey, and Dragonfly—including Exceptions, Configuration, and Data Models
(e.g., RedisException, RedisMessage, ValkeyException, ValkeyMessage, DragonflyException, DragonflyMessage)—to ensure API consistency and simplify backend migration.
Developer Experience Added RedisClient and ValkeyClient, DragonflyClient alias and smart redirection handling for better usability and stability.
Type-Safe Exceptions Clear distinction between connection errors (KeyscopeClientConnectionException),
server errors (KeyscopeClientServerException), and client errors (KeyscopeClientClientException).
Observability Built-in logging.
Multi-Engine Ready Built for the modern ecosystem (Redis, Valkey, Dragonfly).
Identity Switch Use RedisClient, ValkeyClient, or DragonflyClient — whatever suits your project's heart.

🔌 Connection & Configuration

Feature Description
Smart Database Selection First-class support for selecting databases (0-15+) on connection.
Automatically detects Valkey 9.0+ Numbered Clusters to enable multi-database support
in cluster mode, while maintaining backward compatibility with Redis Clusters (DB 0 only).
Explicit Replica Configuration Added explicitReplicas to KeyscopeClientConnectionSettings to manually define replica nodes,
solving connectivity issues in environments where auto-discovery fails.
Cluster Client KeyscopeClusterClient: Dedicated client for automatic command routing in cluster mode.
We recommend using KeyscopeClientClient for Standalone/Sentinel and KeyscopeClientClusterClient for cluster environments.
Built-in Connection Pooling KeyscopeClientPool for efficient connection management (used by Standalone and Cluster clients).
Connection Pool Hardening Smart Release Mechanism: Prevents pool pollution by automatically detecting and
discarding "dirty" connections (e.g., inside Transaction or Pub/Sub) upon release.
Command Timeout Includes a built-in command timeout (via KeyscopeClientConnectionSettings)
to prevent client hangs on non-responsive servers.

🔒 Security & Core

Feature Description
Enterprise Security Native SSL/TLS support compatible with major cloud providers (AWS, Azure, GCP). Supports custom security contexts (including self-signed certificates).
Robust Parsing Full RESP3 parser handling all core data types (+, -, $, *, :).
Pub/Sub Ready (Standalone/Sentinel) subscribe() returns a Subscription object with a Stream and a Future<void> ready for easy and reliable message handling.
Production-Ready Standalone/Sentinel: Stable for production use.
Cluster: Stable for production use with full cluster support.

Libraries

engines/dragonfly_client
This library provides a Dragonfly-compatible interface.
engines/redis_client
This library provides a Redis-compatible interface.
engines/valkey_client
This library provides a Valkey-compatible interface.
keyscope_client
The ultimate multi-engine client for Redis, Valkey, and Dragonfly.
keyscope_client_base
keyscope_client_pool
keyscope_cluster_client_base
keyscope_commands_base
keyscope_connection