npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

bun-redis-tool

v1.0.0

Published

A lightweight, namespaced Redis client tool built for Bun runtime environments

Readme

Redis Tool

A lightweight, high-performance utility for reading, writing, deleting, and listing keys in Redis using namespaces. Built with Bun's native Redis client.

This tool is designed to be multi-purpose:

  1. Console App: Provides clean, human-readable output in your terminal when run directly.
  2. Subprocess: Outputs exact raw strings (without extra newlines or formatting) when spawned by another application, making it perfectly suited for inter-process communication.
  3. Importable Module: Can be compiled to a single file and imported directly into other Bun runtime files.

Prerequisites

  • Bun installed on your machine.
  • A running Redis server.

Configuration

By default, Bun's Redis client will attempt to connect to redis://localhost:6379. You can override this by setting the REDIS_URL environment variable:

export REDIS_URL="redis://username:password@your-redis-host:6379"

Compilation & Bundling

You can compile and bundle the tool in two different formats:

1. Bundled Single JS File (For importing in other Bun files)

To bundle the tool into a single module file that you can import in other Bun projects:

bun run build

This outputs a single-file bundle to dist/redis_tool.js.

2. Standalone Executable (CLI)

To compile the script into a single, standalone binary:

bun run compile

This compiles the tool into the standalone executable redis-tool.

Usage as an Importable Module

You can import RedisTool from the bundled single-file build in any other Bun runtime file. Below are comprehensive examples covering everything the module can do.

1. Initialization and Connection Modes

The RedisTool class is highly flexible. It accepts the namespace as the first argument, and optionally a Redis client configuration or existing instance as the second argument:

import { RedisTool } from "./dist/redis_tool.js";
import { RedisClient } from "bun";

// Mode A: Connect using default configuration (uses REDIS_URL environment variable or localhost:6379)
const cache = new RedisTool("cache");

// Mode B: Connect to a custom Redis URL string
const db = new RedisTool("users", "redis://:my-secret-password@redis-host:6379");

// Mode C: Reuse an existing client connection (ideal for multiple namespaces to avoid opening extra socket connections)
const sharedClient = new RedisClient();
const sessions = new RedisTool("session", sharedClient);
const metrics = new RedisTool("metric", sharedClient);

2. Reading and Writing Data

The tool automatically prefixes keys with the namespace (e.g. namespace:key).

// A. Write a persistent value (string)
await cache.write("theme", "dark");

// B. Read a value (returns string or null if key does not exist)
const theme = await cache.read("theme"); // "dark"
const missing = await cache.read("nonexistent"); // null

// C. Storing and retrieving JSON objects
const userObj = { id: 42, name: "Alice", roles: ["admin"] };
await cache.write("user_42", JSON.stringify(userObj));

const rawUser = await cache.read("user_42");
if (rawUser) {
  const user = JSON.parse(rawUser);
  console.log(user.name); // "Alice"
}

3. Expiration and TTL (Time-To-Live)

You can specify a TTL in seconds when writing a key.

// Write a key that automatically expires after 10 minutes (600 seconds)
await cache.write("temp_token", "abc123xyz", 600);

4. Listing Keys

You can query all keys belonging to the current namespace.

// Set some keys
await cache.write("key_a", "val_a");
await cache.write("key_b", "val_b");

// List all keys (returns string[] of matching keys, including namespace prefix)
const allKeys = await cache.list();
console.log(allKeys); // ["cache:key_a", "cache:key_b"]

5. Deleting Data

// A. Delete a single key (returns number of keys deleted: 1 if deleted, 0 if it didn't exist)
const deletedCount = await cache.delete("key_a"); // 1
const deleteNonexistent = await cache.delete("key_a"); // 0

// B. Delete ALL keys within the namespace (Clear)
// This finds all keys matching "namespace:*" and deletes them at once
const clearedCount = await cache.clear();
console.log(`Cleared ${clearedCount} namespace keys`);

6. Closing Connections

Always clean up connections once you are done using the client:

cache.close();
// Note: If you passed an existing RedisClient to the constructor,
// calling close() on RedisTool will also close that shared client.

CLI Usage

The tool accepts up to five positional arguments depending on the action: [action] [namespace] [key] [value] [ttl_in_seconds]

(Notes: The key is optional for list and clear. The value is required for write. The ttl_in_seconds is optional for write.)

Running directly with Bun

Write a persistent value:

bun run redis_tool.ts write myapp session_id "xyz_12345"

Write a value that expires (e.g., 3600 seconds / 1 hour):

bun run redis_tool.ts write myapp temp_session "abc_987" 3600

Read a value:

bun run redis_tool.ts read myapp session_id

Delete a value:

bun run redis_tool.ts delete myapp session_id

List all keys in a namespace:

bun run redis_tool.ts list myapp

Delete all keys in a namespace (Clear):

bun run redis_tool.ts clear myapp

Running the Standalone Executable

Once compiled, you can run the binary directly:

./redis-tool write myapp test "hello world"
./redis-tool read myapp test

If you move the compiled binary to your /usr/local/bin folder, you can run it from any directory:

sudo mv redis-tool /usr/local/bin/
redis-tool list myapp

Usage as a Subprocess

Because redis_tool.ts automatically detects when it is not running in a TTY terminal, it strips conversational formatting and trailing newlines from output operations. This makes it incredibly easy to consume the stdout stream from another script.

Example: Reading a single value

async function readValue() {
  const readProc = Bun.spawn(["redis-tool", "read", "myapp", "test"]);
  const output = await new Response(readProc.stdout).text();
  console.log("Read from subprocess:", output); 
}

Example: Parsing a list of keys

async function listKeys() {
  const listProc = Bun.spawn(["redis-tool", "list", "myapp"]);
  const output = await new Response(listProc.stdout).text();
  
  // Split the raw string into a clean array of keys
  const keysArray = output.split("\n").filter(Boolean); 
  console.log("Keys found:", keysArray);
}

How it Works (Namespaces)

When you provide a namespace and a key, the tool automatically joins them with a colon (:). For example, running redis-tool write cache user_1 "Alice" will execute SET cache:user_1 "Alice" under the hood. If you provide a TTL of 60, it will follow up with an EXPIRE cache:user_1 60 command. Similarly, redis-tool list cache executes a KEYS cache:* pattern match to find all relevant records.