[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-3803":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":16,"compositeScore":19,"rankGlobal":10,"rankLanguage":10,"license":20,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":23,"topics":24,"createdAt":10,"pushedAt":10,"updatedAt":28,"readmeContent":29,"aiSummary":30,"trendingCount":16,"starSnapshotCount":16,"syncStatus":31,"lastSyncTime":32,"discoverSource":33},3803,"node-redis","redis\u002Fnode-redis","redis","Redis Node.js client","https:\u002F\u002Fredis.js.org\u002F",null,"TypeScript",17542,1957,282,208,0,8,25,76.38,"MIT License",false,"master",true,[5,25,7,26,27],"nodejs","redis-client","redis-cluster","2026-06-12 04:00:19","# Node-Redis\n\n[![Tests](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Fredis\u002Fnode-redis\u002Ftests.yml?branch=master)](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Factions\u002Fworkflows\u002Ftests.yml)\n[![Coverage](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fredis\u002Fnode-redis\u002Fbranch\u002Fmaster\u002Fgraph\u002Fbadge.svg?token=xcfqHhJC37)](https:\u002F\u002Fcodecov.io\u002Fgh\u002Fredis\u002Fnode-redis)\n[![License](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Flicense\u002Fredis\u002Fnode-redis.svg)](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002FLICENSE)\n\n[![Discord](https:\u002F\u002Fimg.shields.io\u002Fdiscord\u002F697882427875393627.svg?style=social&logo=discord)](https:\u002F\u002Fdiscord.gg\u002Fredis)\n[![Twitch](https:\u002F\u002Fimg.shields.io\u002Ftwitch\u002Fstatus\u002Fredisinc?style=social)](https:\u002F\u002Fwww.twitch.tv\u002Fredisinc)\n[![YouTube](https:\u002F\u002Fimg.shields.io\u002Fyoutube\u002Fchannel\u002Fviews\u002FUCD78lHSwYqMlyetR0_P4Vig?style=social)](https:\u002F\u002Fwww.youtube.com\u002Fredisinc)\n[![Twitter](https:\u002F\u002Fimg.shields.io\u002Ftwitter\u002Ffollow\u002Fredisinc?style=social)](https:\u002F\u002Ftwitter.com\u002Fredisinc)\n\nnode-redis is a modern, high performance [Redis](https:\u002F\u002Fredis.io) client for Node.js.\n\n## How do I Redis?\n\n[Learn for free at Redis University](https:\u002F\u002Funiversity.redis.com\u002F)\n\n[Build faster with the Redis Launchpad](https:\u002F\u002Flaunchpad.redis.com\u002F)\n\n[Try the Redis Cloud](https:\u002F\u002Fredis.com\u002Ftry-free\u002F)\n\n[Dive in developer tutorials](https:\u002F\u002Fdeveloper.redis.com\u002F)\n\n[Join the Redis community](https:\u002F\u002Fredis.com\u002Fcommunity\u002F)\n\n[Work at Redis](https:\u002F\u002Fredis.com\u002Fcompany\u002Fcareers\u002Fjobs\u002F)\n\n## Installation\n\nStart a redis via docker:\n\n```bash\ndocker run -p 6379:6379 -d redis:8.0-rc1\n```\n\nTo install node-redis, simply:\n\n```bash\nnpm install redis\n```\n> \"redis\" is the \"whole in one\" package that includes all the other packages. If you only need a subset of the commands,\n> you can install the individual packages. See the list below.\n\n## Packages\n\n| Name                                           | Description                                                                                 |\n| ---------------------------------------------- | ------------------------------------------------------------------------------------------- |\n| [`redis`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fredis)                    | The client with all the [\"redis-stack\"](https:\u002F\u002Fgithub.com\u002Fredis-stack\u002Fredis-stack) modules |\n| [`@redis\u002Fclient`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fclient)           | The base clients (i.e `RedisClient`, `RedisCluster`, etc.)                                  |\n| [`@redis\u002Fbloom`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fbloom)             | [Redis Bloom](https:\u002F\u002Fredis.io\u002Fdocs\u002Fdata-types\u002Fprobabilistic\u002F) commands                     |\n| [`@redis\u002Fjson`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fjson)               | [Redis JSON](https:\u002F\u002Fredis.io\u002Fdocs\u002Fdata-types\u002Fjson\u002F) commands                               |\n| [`@redis\u002Fsearch`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fsearch)           | [RediSearch](https:\u002F\u002Fredis.io\u002Fdocs\u002Finteract\u002Fsearch-and-query\u002F) commands                     |\n| [`@redis\u002Ftime-series`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Ftime-series) | [Redis Time-Series](https:\u002F\u002Fredis.io\u002Fdocs\u002Fdata-types\u002Ftimeseries\u002F) commands                  |\n| [`@redis\u002Fentraid`](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Ftree\u002Fmaster\u002Fpackages\u002Fentraid)         | Secure token-based authentication for Redis clients using Microsoft Entra ID                |\n\n> Looking for a high-level library to handle object mapping?\n> See [redis-om-node](https:\u002F\u002Fgithub.com\u002Fredis\u002Fredis-om-node)!\n\n\n## Usage\n\n### Basic Example\n\n```typescript\nimport { createClient } from \"redis\";\n\nconst client = await createClient()\n  .on(\"error\", (err) => console.log(\"Redis Client Error\", err))\n  .connect();\n\nawait client.set(\"key\", \"value\");\nconst value = await client.get(\"key\");\nclient.destroy();\n```\n\nThe above code connects to localhost on port 6379. To connect to a different host or port, use a connection string in\nthe format `redis[s]:\u002F\u002F[[username][:password]@][host][:port][\u002Fdb-number]`:\n\n```typescript\ncreateClient({\n  url: \"redis:\u002F\u002Falice:foobared@awesome.redis.server:6380\",\n});\n```\n\nYou can also use discrete parameters, UNIX sockets, and even TLS to connect. Details can be found in\nthe [client configuration guide](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fclient-configuration.md).\n\nTo check if the the client is connected and ready to send commands, use `client.isReady` which returns a boolean.\n`client.isOpen` is also available. This returns `true` when the client's underlying socket is open, and `false` when it\nisn't (for example when the client is still connecting or reconnecting after a network error).\n\n### Redis Commands\n\nThere is built-in support for all of the [out-of-the-box Redis commands](https:\u002F\u002Fredis.io\u002Fcommands). They are exposed\nusing the raw Redis command names (`HSET`, `HGETALL`, etc.) and a friendlier camel-cased version (`hSet`, `hGetAll`,\netc.):\n\n```typescript\n\u002F\u002F raw Redis commands\nawait client.HSET(\"key\", \"field\", \"value\");\nawait client.HGETALL(\"key\");\n\n\u002F\u002F friendly JavaScript commands\nawait client.hSet(\"key\", \"field\", \"value\");\nawait client.hGetAll(\"key\");\n```\n\nModifiers to commands are specified using a JavaScript object:\n\n```typescript\nawait client.set(\"key\", \"value\", {\n  EX: 10,\n  NX: true,\n});\n```\n\nReplies will be transformed into useful data structures:\n\n```typescript\nawait client.hGetAll(\"key\"); \u002F\u002F { field1: 'value1', field2: 'value2' }\nawait client.hVals(\"key\"); \u002F\u002F ['value1', 'value2']\n```\n\n`Buffer`s are supported as well:\n\n```typescript\nconst client = createClient().withTypeMapping({\n  [RESP_TYPES.BLOB_STRING]: Buffer\n});\n\nawait client.hSet(\"key\", \"field\", Buffer.from(\"value\")); \u002F\u002F 'OK'\nawait client.hGet(\"key\", \"field\"); \u002F\u002F { field: \u003CBuffer 76 61 6c 75 65> }\n\n```\n\nFor commands that return serialized binary payloads, such as `DUMP`, map blob strings to `Buffer` before using the result with commands like `RESTORE`:\n\n```typescript\nconst binaryClient = createClient().withTypeMapping({\n  [RESP_TYPES.BLOB_STRING]: Buffer\n});\n\nconst dump = await binaryClient.dump(\"source\");\nawait binaryClient.restore(\"destination\", 0, dump);\n```\n\n### Unsupported Redis Commands\n\nIf you want to run commands and\u002For use arguments that Node Redis doesn't know about (yet!) use `.sendCommand()`:\n\n```typescript\nawait client.sendCommand([\"SET\", \"key\", \"value\", \"NX\"]); \u002F\u002F 'OK'\n\nawait client.sendCommand([\"HGETALL\", \"key\"]); \u002F\u002F ['key1', 'field1', 'key2', 'field2']\n```\n\n_Note: the [API is different when using a cluster](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fclustering.md#unsupported-redis-commands)._\n\n### Transactions (Multi\u002FExec)\n\nStart a [transaction](https:\u002F\u002Fredis.io\u002Ftopics\u002Ftransactions) by calling `.multi()`, then chaining your commands. When\nyou're done, call `.exec()` and you'll get an array back with your results:\n\n```typescript\nawait client.set(\"another-key\", \"another-value\");\n\nconst [setKeyReply, otherKeyValue] = await client\n  .multi()\n  .set(\"key\", \"value\")\n  .get(\"another-key\")\n  .exec(); \u002F\u002F ['OK', 'another-value']\n```\n\nYou can also [watch](https:\u002F\u002Fredis.io\u002Ftopics\u002Ftransactions#optimistic-locking-using-check-and-set) keys by calling\n`.watch()`. Your transaction will abort if any of the watched keys change.\n\n\n### Blocking Commands\n\nIn v4, `RedisClient` had the ability to create a pool of connections using an \"Isolation Pool\" on top of the \"main\"\nconnection. However, there was no way to use the pool without a \"main\" connection:\n\n```javascript\nconst client = await createClient()\n  .on(\"error\", (err) => console.error(err))\n  .connect();\n\nawait client.ping(client.commandOptions({ isolated: true }));\n```\n\nIn v5 we've extracted this pool logic into its own class—`RedisClientPool`:\n\n```javascript\nconst pool = await createClientPool()\n  .on(\"error\", (err) => console.error(err))\n  .connect();\n\nawait pool.ping();\n```\n\n\n### Pub\u002FSub\n\nSee the [Pub\u002FSub overview](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fpub-sub.md).\n\n### Scan Iterator\n\n[`SCAN`](https:\u002F\u002Fredis.io\u002Fcommands\u002Fscan) results can be looped over\nusing [async iterators](https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FJavaScript\u002FReference\u002FGlobal_Objects\u002FSymbol\u002FasyncIterator):\n\n```typescript\nfor await (const keys of client.scanIterator()) {\n  console.log(keys, await client.mGet(keys));\n}\n```\n\nThis works with `HSCAN`, `SSCAN`, and `ZSCAN` too:\n\n```typescript\nfor await (const { field, value } of client.hScanIterator(\"hash\")) {\n}\nfor await (const member of client.sScanIterator(\"set\")) {\n}\nfor await (const { score, value } of client.zScanIterator(\"sorted-set\")) {\n}\n```\n\nYou can override the default options by providing a configuration object:\n\n```typescript\nclient.scanIterator({\n  TYPE: \"string\", \u002F\u002F `SCAN` only\n  MATCH: \"pattern*\",\n  COUNT: 100,\n});\n```\n\n### Compare-and-Set\u002FDelete (CAS\u002FCAD)\n\n> **Note**: CAS\u002FCAD operations were introduced in Redis 8.4\n\n```typescript\n\u002F\u002F Conditionally update only if the current value matches\nawait client.set(\"key\", \"new-value\", { condition: \"IFEQ\", matchValue: \"old-value\" });\n\n\u002F\u002F Conditionally delete only if the current value matches\nawait client.delEx(\"key\", { condition: \"IFEQ\", matchValue: \"expected-value\" });\n```\n\n#### Local Digest\n\n> **Note**: This feature requires the optional `@node-rs\u002Fxxhash` peer dependency.\n\nThe `digest` helper computes an XXH3 64-bit hash locally, matching what Redis computes via the `DIGEST` command. This is useful for CAS\u002FCAD operations with large values where comparing the full value would be inefficient.\n\n```bash\nnpm install @node-rs\u002Fxxhash\n```\n\n```typescript\nimport { digest } from \"redis\";\n\nconst hash = await digest(\"my-value\");\n\nawait client.set(\"key\", \"new-value\", { condition: \"IFDEQ\", matchValue: hash });\n```\n\n### Disconnecting\n\nThe `QUIT` command has been deprecated in Redis 7.2 and should now also be considered deprecated in Node-Redis. Instead\nof sending a `QUIT` command to the server, the client can simply close the network connection.\n\n`client.QUIT\u002Fquit()` is replaced by `client.close()`. and, to avoid confusion, `client.disconnect()` has been renamed to\n`client.destroy()`.\n\n```typescript\nclient.destroy();\n```\n### Client Side Caching\n\nNode Redis v5 adds support for [Client Side Caching](https:\u002F\u002Fredis.io\u002Fdocs\u002Fmanual\u002Fclient-side-caching\u002F), which enables clients to cache query results locally. The Redis server will notify the client when cached results are no longer valid.\n\n```typescript\n\u002F\u002F Enable client side caching with RESP3\nconst client = createClient({\n  RESP: 3,\n  clientSideCache: {\n    ttl: 0,             \u002F\u002F Time-to-live (0 = no expiration)\n    maxEntries: 0,      \u002F\u002F Maximum entries (0 = unlimited)\n    evictPolicy: \"LRU\"  \u002F\u002F Eviction policy: \"LRU\" or \"FIFO\"\n  }\n});\n```\n\nSee the [V5 documentation](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fv5.md#client-side-caching) for more details and advanced usage.\n\n### Auto-Pipelining\n\nNode Redis will automatically pipeline requests that are made during the same \"tick\".\n\n```typescript\nclient.set(\"Tm9kZSBSZWRpcw==\", \"users:1\");\nclient.sAdd(\"users:1:tokens\", \"Tm9kZSBSZWRpcw==\");\n```\n\nOf course, if you don't do something with your Promises you're certain to\nget [unhandled Promise exceptions](https:\u002F\u002Fnodejs.org\u002Fapi\u002Fprocess.html#process_event_unhandledrejection). To take\nadvantage of auto-pipelining and handle your Promises, use `Promise.all()`.\n\n```typescript\nawait Promise.all([\n  client.set(\"Tm9kZSBSZWRpcw==\", \"users:1\"),\n  client.sAdd(\"users:1:tokens\", \"Tm9kZSBSZWRpcw==\"),\n]);\n```\n\n### Sentinel\n\nLook at the [sentinel section](docs\u002Fsentinel.md) to figure out how to use this library with sentinels.\n\n### Programmability\n\nSee the [Programmability overview](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fprogrammability.md).\n\n### Clustering\n\nCheck out the [Clustering Guide](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fclustering.md) when using Node Redis to connect to a Redis Cluster.\n\n### OpenTelemetry\n\n#### OpenTelemetry Metrics Instrumentation\n\n```typescript\nimport { createClient, OpenTelemetry } from \"redis\";\n\nOpenTelemetry.init({\n  metrics: {\n    enabled: true\n  }\n});\n\nconst client = createClient()\n\nawait client.connect();\n\u002F\u002F ... use the client as usual\n```\n\n**Important:** Initializing `OpenTelemetry` only enables node-redis metrics instrumentation and requires both `@opentelemetry\u002Fapi` and an OpenTelemetry SDK configured in your application.\n\n**Important:** Initialize `OpenTelemetry` before creating Redis clients.\nFor SDK\u002Fprovider\u002Fexporter setup, verification, and advanced configuration, see:\n\n- [OpenTelemetry Metrics docs](.\u002Fdocs\u002Fotel-metrics.md)\n- [OpenTelemetry Metrics example](.\u002Fexamples\u002Fotel-metrics.js)\n\n### Diagnostics Channel\n\nNode Redis publishes telemetry through Node.js [`diagnostics_channel`](https:\u002F\u002Fnodejs.org\u002Fapi\u002Fdiagnostics_channel.html), enabling APM tools and custom instrumentation to observe commands, connections, and internal events. See the [Diagnostics Channel guide](.\u002Fdocs\u002Fdiagnostics-channel.md) for the full channel reference and usage examples.\n\n### Events\n\nThe Node Redis client class is an Nodejs EventEmitter and it emits an event each time the network status changes:\n\n| Name                    | When                                                                               | Listener arguments                                        |\n| ----------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------- |\n| `connect`               | Initiating a connection to the server                                              | _No arguments_                                            |\n| `ready`                 | Client is ready to use                                                             | _No arguments_                                            |\n| `end`                   | Connection has been closed (via `.disconnect()`)                                   | _No arguments_                                            |\n| `error`                 | An error has occurred—usually a network issue such as \"Socket closed unexpectedly\" | `(error: Error)`                                          |\n| `reconnecting`          | Client is trying to reconnect to the server                                        | _No arguments_                                            |\n| `sharded-channel-moved` | See [here](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fpub-sub.md#sharded-channel-moved-event)                          | See [here](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fpub-sub.md#sharded-channel-moved-event) |\n| `invalidate`            | Client Tracking is on with `emitInvalidate` and a key is invalidated               | `(key: RedisItem \\| null)`                                 |\n\n> :warning: You **MUST** listen to `error` events. If a client doesn't have at least one `error` listener registered and\n> an `error` occurs, that error will be thrown and the Node.js process will exit. See the [ > `EventEmitter` docs](https:\u002F\u002Fnodejs.org\u002Fapi\u002Fevents.html#events_error_events) for more details.\n\n> The client will not emit [any other events](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fv3-to-v4.md#all-the-removed-events) beyond those listed above.\n\n## Supported Redis versions\n\nNode Redis is supported with the following versions of Redis:\n\nSee [Supported Redis Versions](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002FSUPPORTED_REDIS_VERSIONS.md).\n\n## Migration\n\n- [From V3 to V4](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fv3-to-v4.md)\n- [From V4 to V5](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fv4-to-v5.md)\n- [V5](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002Fdocs\u002Fv5.md)\n\n## Contributing\n\nIf you'd like to contribute, check out the [contributing guide](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002FCONTRIBUTING.md).\n\nThank you to all the people who already contributed to Node Redis!\n\n[![Contributors](https:\u002F\u002Fcontrib.rocks\u002Fimage?repo=redis\u002Fnode-redis)](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fgraphs\u002Fcontributors)\n\n## License\n\nThis repository is licensed under the \"MIT\" license. See [LICENSE](https:\u002F\u002Fgithub.com\u002Fredis\u002Fnode-redis\u002Fblob\u002Fmaster\u002FLICENSE).\n","node-redis 是一个为 Node.js 设计的现代化高性能 Redis 客户端。它支持包括 Redis 集群在内的多种核心功能，并且基于 TypeScript 开发，保证了代码质量和类型安全。此外，该项目还提供了丰富的模块化选项，如布隆过滤器、JSON 支持和全文搜索等，满足不同场景下的需求。适用于需要与 Redis 数据库进行高效交互的各种 Node.js 应用程序开发场景，无论是简单的缓存解决方案还是复杂的数据处理任务都能轻松应对。",2,"2026-06-11 02:56:24","top_language"]