{"id":26690769,"url":"https://github.com/reactjs/reselect","last_synced_at":"2025-03-26T16:01:06.957Z","repository":{"id":34433335,"uuid":"38366638","full_name":"reduxjs/reselect","owner":"reduxjs","description":"Selector library for Redux","archived":false,"fork":false,"pushed_at":"2025-03-16T19:43:09.000Z","size":6100,"stargazers_count":19053,"open_issues_count":41,"forks_count":674,"subscribers_count":163,"default_branch":"master","last_synced_at":"2025-03-24T22:11:14.280Z","etag":null,"topics":["memoized-selectors","redux"],"latest_commit_sha":null,"homepage":null,"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/reduxjs.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":"AUTHORS","dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-07-01T11:06:45.000Z","updated_at":"2025-03-24T06:25:04.000Z","dependencies_parsed_at":"2023-02-18T20:16:08.861Z","dependency_job_id":"48c03af6-8e57-44b9-9f60-6e46dbb6a0f1","html_url":"https://github.com/reduxjs/reselect","commit_stats":{"total_commits":1055,"total_committers":113,"mean_commits":9.336283185840708,"dds":0.6663507109004739,"last_synced_commit":"1c3fc05f041d32cd69c11a7f7deccf0bce6f4598"},"previous_names":["reactjs/reselect","faassen/reselect"],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reduxjs%2Freselect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reduxjs%2Freselect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reduxjs%2Freselect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reduxjs%2Freselect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reduxjs","download_url":"https://codeload.github.com/reduxjs/reselect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245689494,"owners_count":20656416,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["memoized-selectors","redux"],"created_at":"2025-03-26T16:00:36.751Z","updated_at":"2025-03-26T16:01:06.938Z","avatar_url":"https://github.com/reduxjs.png","language":"TypeScript","readme":"# Reselect\n\n[![npm package][npm-badge]][npm][![Coveralls][coveralls-badge]][coveralls][![GitHub Workflow Status][build-badge]][build]![TypeScript][typescript-badge]\n\nA library for creating memoized \"selector\" functions. Commonly used with Redux, but usable with any plain JS immutable data as well.\n\n- Selectors can compute derived data, allowing [Redux] to store the minimal possible state.\n- Selectors are efficient. A selector is not recomputed unless one of its arguments changes.\n- Selectors are composable. They can be used as input to other selectors.\n\nThe **Redux docs usage page on [Deriving Data with Selectors](https://redux.js.org/usage/deriving-data-selectors)** covers the purpose and motivation for selectors, why memoized selectors are useful, typical Reselect usage patterns, and using selectors with [React-Redux].\n\n## Installation\n\n### Redux Toolkit\n\nWhile Reselect is not exclusive to [Redux], it is already included by default in [the official Redux Toolkit package](https://redux-toolkit.js.org) - no further installation needed.\n\n```ts\nimport { createSelector } from '@reduxjs/toolkit'\n```\n\n### Standalone\n\nFor standalone usage, install the `reselect` package:\n\n```bash\n# NPM\nnpm install reselect\n\n# Yarn\nyarn add reselect\n```\n\n---\n\n## Documentation\n\nThe Reselect docs are available at **https://reselect.js.org**, and include usage guides and API references:\n\n- [**Introduction**](#https://reselect.js.org/introduction/getting-started)\n- [**How Does Reselect Work?**](#https://reselect.js.org/introduction/how-does-reselect-work)\n- **API Reference**:\n  - **[`createSelector`]**\n  - **[`createSelectorCreator`]**\n  - **[`createStructuredSelector`]**\n  - [**Development-Only Stability Checks**](#https://reselect.js.org/api/development-only-stability-checks)\n  - **[`lruMemoize`]**\n  - **[`weakMapMemoize`]**\n- [**FAQ**](#https://reselect.js.org/FAQ)\n\n## Basic Usage\n\nReselect exports a [`createSelector`] API, which generates memoized selector functions. [`createSelector`] accepts one or more [input selectors], which extract values from arguments, and a [result function] function that receives the extracted values and should return a derived value. If the generated [output selector] is called multiple times, the output will only be recalculated when the extracted values have changed.\n\nYou can play around with the following **example** in [this CodeSandbox](https://codesandbox.io/s/reselect-example-g3k9gf?file=/src/index.js):\n\n```ts\nimport { createSelector } from 'reselect'\n\ninterface RootState {\n  todos: { id: number; completed: boolean }[]\n  alerts: { id: number; read: boolean }[]\n}\n\nconst state: RootState = {\n  todos: [\n    { id: 0, completed: false },\n    { id: 1, completed: true }\n  ],\n  alerts: [\n    { id: 0, read: false },\n    { id: 1, read: true }\n  ]\n}\n\nconst selectCompletedTodos = (state: RootState) =\u003e {\n  console.log('selector ran')\n  return state.todos.filter(todo =\u003e todo.completed === true)\n}\n\nselectCompletedTodos(state) // selector ran\nselectCompletedTodos(state) // selector ran\nselectCompletedTodos(state) // selector ran\n\nconst memoizedSelectCompletedTodos = createSelector(\n  [(state: RootState) =\u003e state.todos],\n  todos =\u003e {\n    console.log('memoized selector ran')\n    return todos.filter(todo =\u003e todo.completed === true)\n  }\n)\n\nmemoizedSelectCompletedTodos(state) // memoized selector ran\nmemoizedSelectCompletedTodos(state)\nmemoizedSelectCompletedTodos(state)\n\nconsole.log(selectCompletedTodos(state) === selectCompletedTodos(state)) //=\u003e false\n\nconsole.log(\n  memoizedSelectCompletedTodos(state) === memoizedSelectCompletedTodos(state)\n) //=\u003e true\n```\n\nAs you can see from the example above, `memoizedSelectCompletedTodos` does not run the second or third time, but we still get the same return value as last time.\n\nIn addition to skipping unnecessary recalculations, `memoizedSelectCompletedTodos` returns the existing result reference if there is no recalculation. This is important for libraries like [React-Redux] or [React] that often rely on reference equality checks to optimize UI updates.\n\n---\n\n## Terminology\n\n- \u003ca name=\"selector-function\"\u003e\u003c/a\u003e[**Selector Function**](#selector-function): A function that accepts one or more JavaScript values as arguments, and derives a result. When used with [Redux], the first argument is typically the entire Redux store state.\n- \u003ca name=\"input-selectors\"\u003e\u003c/a\u003e[**input selectors**](#input-selectors): Basic selector functions used as building blocks for creating a memoized selector. They are passed as the first argument(s) to [`createSelector`], and are called with all selector arguments. They are responsible for extracting and providing necessary values to the [result function].\n- \u003ca name=\"output-selector\"\u003e\u003c/a\u003e[**Output Selector**](#output-selector): The actual memoized selectors created by [`createSelector`].\n- \u003ca name=\"result-function\"\u003e\u003c/a\u003e[**Result Function**](#result-function): The function that comes after the [input selectors]. It takes the [input selectors]' return values as arguments and returns a result.\n- \u003ca name=\"dependencies\"\u003e\u003c/a\u003e[**`Dependencies`**](#dependencies): Same as [input selectors]. They are what the [output selector] \"depends\" on.\n\nThe below example serves as a visual aid:\n\n```ts\nconst outputSelector = createSelector(\n  [inputSelector1, inputSelector2, inputSelector3], // synonymous with `dependencies`.\n  resultFunc // Result function\n)\n```\n\n---\n\n## What's New in 5.0.0?\n\nVersion 5.0.0 introduces several new features and improvements:\n\n- **Customization Enhancements**:\n\n  - Added the ability to pass an options object to [`createSelectorCreator`], allowing for customized `memoize` and `argsMemoize` functions, alongside their respective options (`memoizeOptions` and `argsMemoizeOptions`).\n  - The [`createSelector`] function now supports direct customization of `memoize` and `argsMemoize` within its options object.\n\n- **Memoization Functions**:\n\n  - Introduced new experimental memoization functions: `weakMapMemoize` and `unstable_autotrackMemoize`.\n  - Incorporated `memoize` and `argsMemoize` into the [output selector fields] for debugging purposes.\n\n- **TypeScript Support and Performance**:\n\n  - Discontinued support for TypeScript versions below 4.7, aligning with modern TypeScript features.\n  - Significantly improved TypeScript performance for nesting [output selectors][output selector]. The nesting limit has increased from approximately 8 to around 30 [output selectors][output selector], greatly reducing the occurrence of the infamous `Type instantiation is excessively deep and possibly infinite` error.\n\n- **Selector API Enhancements**:\n\n  - Removed the second overload of `createStructuredSelector` due to its susceptibility to runtime errors.\n\n- **Additional Functionalities**:\n\n  - Added `dependencyRecomputations` and `resetDependencyRecomputations` to the [output selector fields]. These additions provide greater control and insight over [input selectors], complementing the new `argsMemoize` API.\n  - Introduced `inputStabilityCheck`, a development tool that runs the [input selectors] twice using the same arguments and triggers a warning If they return differing results for the same call.\n  - Introduced `identityFunctionCheck`, a development tool that checks to see if the [result function] returns its own input.\n\nThese updates aim to enhance flexibility, performance, and developer experience. For detailed usage and examples, refer to the updated documentation sections for each feature.\n\n- **Breaking Changes**:\n\n  - Removed `ParametricSelector` and `OutputParametricSelector` types. Their functionalities are now integrated into `Selector` and `OutputSelector` respectively, which inherently support additional parameters.\n\n\u003cdiv align=\"right\"\u003e[ \u003ca href=\"installation\"\u003e↑ Back to top ↑\u003c/a\u003e ]\u003c/div\u003e\n\n---\n\n## License\n\nMIT\n\n## References\n\n\u003cdetails\u003e\u003csummary\u003e\u003cb\u003eClick to Expand\u003c/b\u003e\u003c/summary\u003e\n\nOriginally inspired by getters in [NuclearJS](https://github.com/optimizely/nuclear-js.git), [subscriptions](https://github.com/Day8/re-frame#just-a-read-only-cursor) in [re-frame](https://github.com/Day8/re-frame) and this [proposal](https://github.com/reduxjs/redux/pull/169) from [speedskater](https://github.com/speedskater).\n\n[typescript-badge]: https://img.shields.io/badge/TypeScript-v4%2E7%2B-007ACC?style=for-the-badge\u0026logo=TypeScript\u0026logoColor=black\u0026labelColor=blue\u0026color=gray\n[build-badge]: https://img.shields.io/github/actions/workflow/status/reduxjs/reselect/build-and-test-types.yml?branch=master\u0026style=for-the-badge\n[build]: https://github.com/reduxjs/reselect/actions/workflows/build-and-test-types.yml\n[npm-badge]: https://img.shields.io/npm/v/reselect.svg?style=for-the-badge\n[npm]: https://www.npmjs.org/package/reselect\n[coveralls-badge]: https://img.shields.io/coveralls/reduxjs/reselect/master.svg?style=for-the-badge\n[coveralls]: https://coveralls.io/github/reduxjs/reselect\n\n\u003c!-- External Links --\u003e\n\n[Redux]: https://redux.js.org 'Redux'\n[React]: https://react.dev 'React'\n[React-Redux]: https://react-redux.js.org 'React-Redux'\n\n\u003c!-- Internal Links --\u003e\n\n[selector]: #selector-function 'Selector Function'\n[input selectors]: #input-selectors 'Input Selectors'\n[output selector]: #output-selector 'Output Selector'\n[result function]: #result-function 'Result Function'\n[output selector fields]: https://reselect.js.org/api/createSelector#output-selector-fields 'Output Selector Fields'\n[`createSelector`]: https://reselect.js.org/api/createSelector 'createSelector'\n[`createSelectorCreator`]: https://reselect.js.org/api/createSelectorCreator 'createSelectorCreator'\n[`lruMemoize`]: https://reselect.js.org/api/lruMemoize 'lruMemoize'\n[`weakMapMemoize`]: https://reselect.js.org/api/weakMapMemoize 'weakMapMemoize'\n[`createStructuredSelector`]: https://reselect.js.org/api/createStructuredSelector 'createStructuredSelector'\n\n\u003c/details\u003e\n","funding_links":[],"categories":["Uncategorized","Frameworks/Libraries","Code Design","Utilities","Marks"],"sub_categories":["Uncategorized","Coding Playgrounds","Data Store","[React - A JavaScript library for building user interfaces](http://facebook.github.io/react)"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactjs%2Freselect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freactjs%2Freselect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freactjs%2Freselect/lists"}