g14o
Packages@g14o/cache

Setup

Configure createCache with stores, TTL overrides, and build-phase behavior.

Basic setup (Upstash)

lib/cache.ts
import { createCache } from "@g14o/cache";
import { upstashStore } from "@g14o/cache/upstash";
import { logger } from "@/lib/logger";
import { env } from "@/lib/env";

export const { withCache, invalidateCache, invalidateCacheKey } = createCache({
  store: upstashStore({
    url: env.UPSTASH_REDIS_REST_URL,
    token: env.UPSTASH_REDIS_REST_TOKEN,
  }),
  logger,
});

node-redis / ioredis

import { createCache } from "@g14o/cache";
import { redisStore } from "@g14o/cache/redis";
import { createClient } from "redis";

const redis = createClient({ url: process.env.REDIS_URL });
await redis.connect();

export const { withCache } = createCache({ store: redisStore(redis) });

Custom store

import { createStore } from "@g14o/cache";

const store = createStore({
  async read(key) { /* string | null */ },
  async write(key, value, ttlSeconds) { /* persist */ },
  async remove(...keys) { return 0; },
  async list(pattern) { return []; },
});

createCache({ store });

Defaults to JSON serialize/deserialize. undefined round-trips via a string sentinel. Optional serialize / deserialize / prefix are supported; a serializer that returns undefined is coerced to the sentinel before write().

Custom TTL

Flat form (applies to the active environment):

createCache({
  store: upstashStore({ url, token }),
  ttl: { short: 30, long: 900 },
});

Per-environment overrides:

createCache({
  store: upstashStore({ url, token }),
  ttl: {
    development: { short: 30, long: 900 },
    production: { medium: 3600 },
  },
});

Default key strategy

Set a client-level key generator (overridable per withCache call):

createCache({
  store: upstashStore({ url, token }),
  keyGenerator: (prefix, fnName, args) => `${prefix}:${fnName}:${JSON.stringify(args)}`,
});

Legacy redis option

Still supported; wraps upstashStore internally. Prefer store: upstashStore(...) for new code.

Build vs runtime

When no store is configured, dev/test/build use in-memory cache. Production requires an explicit store.

Import isBuildLikePhase() from @g14o/cache/config to branch on build phase.

On this page