本文へ移動
cccskills
無料GitHub で公開

bun-redis

Use when working with Redis in Bun (ioredis, Upstash), caching, pub/sub, session storage, or key-value operations.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md6.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Bun Redis

Redis integration with Bun using popular Redis clients.

Client Options

ClientBest ForInstall
ioredisSelf-hosted Redisbun add ioredis
@upstash/redisServerless/Edgebun add @upstash/redis
redisOfficial Node clientbun add redis

ioredis Setup

import Redis from "ioredis";

// Default connection
const redis = new Redis();

// With options
const redis = new Redis({
  host: "localhost",
  port: 6379,
  password: "secret",
  db: 0,
});

// Connection string
const redis = new Redis("redis://:password@localhost:6379/0");

// TLS connection
const redis = new Redis({
  host: "redis.example.com",
  port: 6380,
  tls: {},
});

Basic Operations

import Redis from "ioredis";

const redis = new Redis();

// Strings
await redis.set("name", "Alice");
await redis.set("count", "100");
await redis.setex("temp", 60, "expires in 60s"); // With TTL

const name = await redis.get("name"); // "Alice"
const count = await redis.incr("count"); // 101
await redis.del("name");

// Check existence
const exists = await redis.exists("name"); // 0 or 1

// TTL
await redis.expire("key", 3600); // Set 1 hour TTL
const ttl = await redis.ttl("key"); // Get remaining TTL

Data Structures

Hashes

// Set hash fields
await redis.hset("user:1", {
  name: "Alice",
  email: "alice@example.com",
  age: "30",
});

// Get single field
const name = await redis.hget("user:1", "name");

// Get all fields
const user = await redis.hgetall("user:1");
// { name: "Alice", email: "...", age: "30" }

// Increment field
await redis.hincrby("user:1", "visits", 1);

Lists

// Add to list
await redis.rpush("queue", "task1", "task2");
await redis.lpush("queue", "urgent");

// Pop from list
const task = await redis.lpop("queue"); // "urgent"
const blocking = await redis.blpop("queue", 5); // Wait 5s

// Range
const items = await redis.lrange("queue", 0, -1);

Sets

// Add members
await redis.sadd("tags", "javascript", "typescript", "bun");

// Check membership
const isMember = await redis.sismember("tags", "bun"); // 1

// Get all members
const tags = await redis.smembers("tags");

// Set operations
await redis.sinter("tags1", "tags2"); // Intersection
await redis.sunion("tags1", "tags2"); // Union

Sorted Sets

// Add with scores
await redis.zadd("leaderboard", 100, "alice", 200, "bob", 150, "charlie");

// Get by rank
const top3 = await redis.zrevrange("leaderboard", 0, 2, "WITHSCORES");

// Get by score range
const highScores = await redis.zrangebyscore("leaderboard", 100, 200);

// Increment score
await redis.zincrby("leaderboard", 50, "alice");

JSON (RedisJSON)

// Requires RedisJSON module
await redis.call("JSON.SET", "user:1", "$", JSON.stringify({
  name: "Alice",
  settings: { theme: "dark" },
}));

const user = await redis.call("JSON.GET", "user:1");
const settings = await redis.call("JSON.GET", "user:1", "$.settings");

Pub/Sub

import Redis from "ioredis";

// Publisher
const pub = new Redis();

// Subscriber
const sub = new Redis();

// Subscribe to channel
sub.subscribe("notifications", (err, count) => {
  console.log(`Subscribed to ${count} channels`);
});

// Handle messages
sub.on("message", (channel, message) => {
  console.log(`${channel}: ${message}`);
});

// Publish
await pub.publish("notifications", JSON.stringify({
  type: "alert",
  message: "Hello!",
}));

// Pattern subscribe
sub.psubscribe("user:*");
sub.on("pmessage", (pattern, channel, message) => {
  console.log(`${pattern} -> ${channel}: ${message}`);
});

Transactions

// Multi/Exec
const results = await redis
  .multi()
  .set("key1", "value1")
  .set("key2", "value2")
  .incr("counter")
  .exec();

// Pipeline (no atomicity, better performance)
const pipeline = redis.pipeline();
pipeline.set("key1", "value1");
pipeline.set("key2", "value2");
pipeline.incr("counter");
const results = await pipeline.exec();

Upstash Redis (Serverless)

import { Redis } from "@upstash/redis";

const redis = new Redis({
  url: process.env.UPSTASH_REDIS_REST_URL,
  token: process.env.UPSTASH_REDIS_REST_TOKEN,
});

// Same API as ioredis
await redis.set("key", "value");
const value = await redis.get("key");

// With automatic JSON serialization
await redis.set("user", { name: "Alice", age: 30 });
const user = await redis.get<{ name: string; age: number }>("user");

Caching Patterns

Cache-Aside

async function getUser(id: string) {
  // Check cache
  const cached = await redis.get(`user:${id}`);
  if (cached) {
    return JSON.parse(cached);
  }

  // Fetch from database
  const user = await db.query.users.findFirst({
    where: eq(users.id, id),
  });

  // Cache for 1 hour
  if (user) {
    await redis.setex(`user:${id}`, 3600, JSON.stringify(user));
  }

  return user;
}

Write-Through

async function updateUser(id: string, data: UserUpdate) {
  // Update database
  await db.update(users).set(data).where(eq(users.id, id));

  // Update cache
  const user = await db.query.users.findFirst({
    where: eq(users.id, id),
  });
  await redis.setex(`user:${id}`, 3600, JSON.stringify(user));

  return user;
}

Rate Limiting

async function rateLimit(key: string, limit: number, window: number) {
  const current = await redis.incr(key);

  if (current === 1) {
    await redis.expire(key, window);
  }

  return current <= limit;
}

// Usage
const allowed = await rateLimit(`rate:${userId}`, 100, 60);
if (!allowed) {
  throw new Error("Rate limit exceeded");
}

Session Storage

import { Hono } from "hono";
import Redis from "ioredis";
import { v4 as uuid } from "uuid";

const redis = new Redis();
const app = new Hono();

app.use("*", async (c, next) => {
  const sessionId = c.req.header("X-Session-Id") || uuid();
  const session = await redis.hgetall(`session:${sessionId}`);

  c.set("session", session);
  c.set("sessionId", sessionId);

  await next();

  // Save session
  const updatedSession = c.get("session");
  if (Object.keys(updatedSession).length > 0) {
    await redis.hset(`session:${sessionId}`, updatedSession);
    await redis.expire(`session:${sessionId}`, 86400); // 24h
  }
});

Common Errors

ErrorCauseFix
ECONNREFUSEDRedis not runningStart Redis server
NOAUTHAuthentication requiredProvide password
WRONGTYPEWrong data typeCheck key type
OOMOut of memoryConfigure maxmemory

When to Load References

Load references/clustering.md when:

  • Redis Cluster setup
  • Sentinel configuration
  • High availability patterns

Load references/lua-scripts.md when:

  • Custom Lua scripts
  • Atomic operations
  • Complex transactions

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

100+ animated React components (Aceternity UI) for Next.js with Tailwind. Use for hero sections, parallax, 3D effects, or encountering animation, shadcn CLI integration errors.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

Secure API authentication with JWT, OAuth 2.0, API keys. Use for authentication systems, third-party integrations, service-to-service communication, or encountering token management, security headers, auth flow errors.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

Creates comprehensive API changelogs documenting breaking changes, deprecations, and migration strategies for API consumers. Use when managing API versions, communicating breaking changes, or creating upgrade guides.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

Verifies API contracts between services using consumer-driven contracts, schema validation, and tools like Pact. Use when testing microservices communication, preventing breaking changes, or validating OpenAPI specifications.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

Master REST and GraphQL API design principles to build intuitive, scalable, and maintainable APIs that delight developers. Use when designing new APIs, reviewing API specifications, or establishing API design standards.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

Implements standardized API error responses with proper status codes, logging, and user-friendly messages. Use when building production APIs, implementing error recovery patterns, or integrating error monitoring services.

日本語の概要は準備中です。原文の説明を表示しています。

secondsky/claude-skills2292026年9月28日 更新

secondsky のスキルをすべて見る

このスキルの問題を報告する