{"id":28403655,"url":"https://github.com/suranig/next-cachex","last_synced_at":"2026-01-29T10:55:10.055Z","repository":{"id":295707398,"uuid":"990934684","full_name":"suranig/next-cachex","owner":"suranig","description":"A distributed, backend-agnostic caching library for Next.js, with built-in locking and full Redis/KeyDB support.","archived":false,"fork":false,"pushed_at":"2025-07-11T22:59:47.000Z","size":208,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-09-28T21:38:24.947Z","etag":null,"topics":["nextjs","shared-cache"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/suranig.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-26T21:52:17.000Z","updated_at":"2025-07-11T22:59:51.000Z","dependencies_parsed_at":"2025-05-27T01:30:07.375Z","dependency_job_id":"ade6ad8c-531c-4a29-9103-c078ce8f848e","html_url":"https://github.com/suranig/next-cachex","commit_stats":null,"previous_names":["suranig/next-cachex"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/suranig/next-cachex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suranig%2Fnext-cachex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suranig%2Fnext-cachex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suranig%2Fnext-cachex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suranig%2Fnext-cachex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/suranig","download_url":"https://codeload.github.com/suranig/next-cachex/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/suranig%2Fnext-cachex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28876468,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-29T10:31:27.438Z","status":"ssl_error","status_checked_at":"2026-01-29T10:31:01.017Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nextjs","shared-cache"],"created_at":"2025-06-01T18:38:16.153Z","updated_at":"2026-01-29T10:55:10.038Z","avatar_url":"https://github.com/suranig.png","language":"TypeScript","readme":"# next-cachex\n\n[![npm version](https://badge.fury.io/js/next-cachex.svg)](https://badge.fury.io/js/next-cachex)\n![npm downloads](https://img.shields.io/npm/dt/next-cachex)\n[![codecov](https://codecov.io/gh/suranig/next-cachex/branch/master/graph/badge.svg)](https://codecov.io/gh/suranig/next-cachex)\n[![GitHub Actions](https://github.com/suranig/next-cachex/actions/workflows/ci.yml/badge.svg)](https://github.com/suranig/next-cachex/actions/workflows/ci.yml)\n[![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)\n[![GitHub](https://img.shields.io/badge/GitHub-suranig%2Fnext--cachex-black?logo=github)](https://github.com/suranig/next-cachex)\n\n## Requirements\n- Next.js 13 or later\n- Node.js 18 or later\n- Redis server (for Redis backend)\n\n## Installation\n\n```sh\n# Using npm\nnpm install next-cachex\n\n# Using yarn\nyarn add next-cachex\n\n# Using pnpm\npnpm add next-cachex\n```\n\n## Development\n\n### Setup\n```sh\n# Clone the repository\ngit clone https://github.com/suranig/next-cachex.git\ncd next-cachex\n\n# Install dependencies\nnpm install\n```\n\n## Dependencies\n- typescript@5 (strict mode)\n- vitest (unit testing)\n- ioredis (Redis backend)\n- @types/node (TypeScript types)\n- eslint (linting)\n- prettier (formatting)\n- husky (pre-commit hooks)\n- typedoc (API documentation)\n\n## Development\n\n### Testing\n```sh\nnpm run test       # Run tests\nnpm run lint       # Run linter\nnpm run coverage   # Run tests with coverage\n```\n\n### Release Process\nTo release a new version:\n\n```sh\n# For a patch release (bug fixes)\nmake release-patch\n\n# For a minor release (new features, backward compatible)\nmake release-minor\n\n# For a major release (breaking changes)\nmake release-major\n```\n\nThis will:\n1. Update the version in package.json\n2. Create a git tag\n3. Push changes and tags to GitHub\n4. Trigger the GitHub Actions workflow that publishes to npm and GitHub Packages\n\n# Assumptions and Technical Specification\n\n1. Project Goal\n- provide a distributed, shared cache handler for Next.js (13+), fully compatible with both App Router (app/) and Pages - - router (pages/), designed for multi-pod environments (Kubernetes, ECS, Vercel, etc.).\n- primary backend at launch: Redis (support for more cache backends in future).\n- solve production-scale cache problems: thundering herd, consistency, TTL, namespacing, easy API for developers.\n\n## Distributed Cache, ISR, and Revalidation\n\n### Why a Shared Cache?\nIn distributed Next.js deployments (multiple pods/containers), a shared cache (like Redis) ensures all instances serve the same data and revalidation is global. Without this, some pods may serve stale data after a revalidate.\n\n### How to Invalidate (Revalidate) Cache\n- **Single key:**\n  ```ts\n  await cacheHandler.backend.del('my-key')\n  ```\n- **All keys for a prefix:**\n  ```ts\n  await cacheHandler.backend.clear()\n  ```\n- **(Optional) Tag-based:**\n  ```ts\n  await cacheHandler.revalidateTag('my-tag') // if implemented\n  ```\n\n### Example: On-demand Revalidation (API Route)\n```ts\nimport { cacheHandler } from 'next-cachex';\n\nexport default async function handler(req, res) {\n  await cacheHandler.backend.del('posts:all');\n  res.status(200).json({ revalidated: true });\n}\n```\n\n## Example: Custom Logger\n\nYou can provide your own logger to capture cache events for debugging, metrics, or production observability:\n\n```ts\nimport { createCacheHandler } from 'next-cachex';\nimport { RedisCacheBackend } from 'next-cachex/backends/redis';\nimport Redis from 'ioredis';\n\nconst redisClient = new Redis();\n\nconst logger = {\n  log: (event) =\u003e {\n    // You can send this to your logger, metrics, or just console.log\n    console.log(`[CACHE]`, event);\n  },\n};\n\nconst cacheHandler = createCacheHandler({\n  backend: new RedisCacheBackend(redisClient, 'myapp:v1'),\n  logger,\n});\n\n// Usage\nconst data = await cacheHandler.fetch('posts:all', fetchPosts, { ttl: 300 });\n```\n\n## Inspirations \u0026 References\n\nThis project draws inspiration and best practices from several leading open-source caching and distributed systems projects:\n\n- [next-boost](https://github.com/next-boost/next-boost): SSR cache with stale-while-revalidate, custom cache keys, and flexible TTL rules. Demonstrates advanced cache control and revalidation patterns for Next.js.\n- [next-shared-cache](https://github.com/caching-tools/next-shared-cache): Modern, production-grade shared cache handler for Next.js, with Redis support, on-demand revalidation, and instrumentation hooks. Strong focus on distributed cache invalidation and DX.\n- [node-redlock](https://github.com/mike-marcacci/node-redlock): Robust distributed locking for Redis, used as a reference for atomic lock implementation and safety in multi-pod environments.\n- [bullmq](https://github.com/taskforcesh/bullmq): Distributed job and queue management with Redis, providing patterns for atomic operations and reliability in distributed systems.\n- [upstash/nextauth-upstash-redis](https://github.com/upstash/examples/tree/main/examples/nextauth-upstash-redis): Example of using Upstash Redis for session and cache management in Next.js, showing best practices for serverless and distributed cache.\n- [apicache](https://github.com/kwhitley/apicache): HTTP cache middleware for Node.js/Express, with flexible cache control and invalidation strategies.\n- [cacheable](https://github.com/jaredwray/cacheable): Generic, pluggable cache abstraction for Node.js, with support for multiple backends and advanced cache policies.\n\nThese projects have influenced the design, API, and operational safety of next-cachex. See their docs for further patterns and advanced use cases.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuranig%2Fnext-cachex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsuranig%2Fnext-cachex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsuranig%2Fnext-cachex/lists"}