All free skills / Other majors

reselect 5.x

Use Reselect ^5.0.0 to build memoized selectors, customize memoization, compose structured results, and account for v5 defaults and API changes.

For
reselect@5.3.0
Verified
2026-09-08, 6 examples executed
Skill package
@modootoday/pmcp-reselect@5.0.0

Use this skill for free

No PMCP login or subscription is required. Download the original instructions, or install the content-only archive with your project's package manager.

Download SKILL.md · Download package archive

npm install --save-dev https://pmcp.build/skills/reselect/5/package.tgz

PMCP discovers the installed package's instructions. Connect your runtime after installation.

Archive integritysha512-30HihA5XtimZ1bXcYKkHrAjg3dVXumWdzw1ue7qB7SJ7cdI0A8Mszc8Xb7zEGx0ZkaeFgLFbe1y3hiSU4+xdPA==

Complete instructions

Verified against reselect@5.3.0 on 2026-09-08. 6 of 6 examples executed.

reselect ^5.0.0

What this package does

reselect is a selector library. Import its functions directly from the package; ordinary use does not require a runner, CLI, build step, framework global, or test runner.

The main exports documented for this version range are:

  • createSelector
  • createSelectorCreator
  • createStructuredSelector
  • lruMemoize
  • weakMapMemoize

createSelector

Pass input selectors either as one array or as separate arguments, followed by a result function and, optionally, an options object. The returned selector is memoized.

In v5, weakMapMemoize is the default for both memoization levels. This differs from v4, where lruMemoize (formerly defaultMemoize) was the default with a cache size of 1.

import assert from 'node:assert/strict'
import { createSelector } from 'reselect'

type State = {
  todos: Array<{ id: number; category: string }>
}

const selectTodosByCategory = createSelector(
  [
    (state: State) => state.todos,
    (_state: State, category: string) => category
  ],
  (todos, category) => todos.filter(todo => todo.category === category)
)

const todos = [
  { id: 1, category: 'work' },
  { id: 2, category: 'home' },
  { id: 3, category: 'work' }
]
const state = { todos }

const first = selectTodosByCategory(state, 'work')
const second = selectTodosByCategory(state, 'work')

assert.deepEqual(first, [
  { id: 1, category: 'work' },
  { id: 3, category: 'work' }
])
assert.strictEqual(first, second)

Use an input selector for every value needed by the result function. Input selectors receive the same arguments as the resulting selector, so additional parameters can be selected without the removed v4-specific ParametricSelector types.

The selector exposes memoization-related fields including dependencyRecomputations, resetDependencyRecomputations, memoize, and argsMemoize.

Per-selector memoization

Pass memoize and memoizeOptions in the third argument to configure one selector. lruMemoize supports configurable cache and equality behavior, including resultEqualityCheck.

import assert from 'node:assert/strict'
import { createSelector, lruMemoize } from 'reselect'

type State = { todos: Array<{ id: number; title: string }> }

const selectTodoIds = createSelector(
  [(state: State) => state.todos],
  todos => todos.map(todo => todo.id),
  {
    memoize: lruMemoize,
    memoizeOptions: {
      resultEqualityCheck: (a: number[], b: number[]) =>
        a.length === b.length && a.every((id, index) => id === b[index])
    }
  }
)

const firstState = { todos: [{ id: 1, title: 'one' }] }
const secondState = { todos: [{ id: 1, title: 'changed elsewhere' }] }

const first = selectTodoIds(firstState)
const second = selectTodoIds(secondState)

assert.deepEqual(first, [1])
assert.strictEqual(first, second)

createSelectorCreator

Use createSelectorCreator to make a family of selectors with shared memoization configuration. The current configuration form takes an options object. The legacy form, memoize, ...memoizeOptions, is also accepted, but prefer the options object in new code.

import assert from 'node:assert/strict'
import { createSelectorCreator, lruMemoize } from 'reselect'

const createShallowEqualSelector = createSelectorCreator({
  memoize: lruMemoize,
  memoizeOptions: {
    resultEqualityCheck: (a: number[], b: number[]) =>
      a.length === b.length && a.every((value, index) => value === b[index])
  }
})

const selectValues = createShallowEqualSelector(
  [(state: { values: number[] }) => state.values],
  values => values.map(value => value)
)

const first = selectValues({ values: [1, 2] })
const second = selectValues({ values: [1, 2] })

assert.deepEqual(first, [1, 2])
assert.strictEqual(first, second)

createStructuredSelector

Pass an object whose values are input selectors. The returned selector computes each value and returns an object with the same keys.

import assert from 'node:assert/strict'
import { createStructuredSelector } from 'reselect'

type State = {
  todos: Record<number, { id: number }>
  alerts: string[]
}

const structuredSelector = createStructuredSelector({
  todos: (state: State) => state.todos,
  alerts: (state: State) => state.alerts,
  todoById: (state: State, id: number) => state.todos[id]
})

const todo = { id: 7 }
const state = { todos: { 7: todo }, alerts: ['late'] }

assert.deepEqual(structuredSelector(state, 7), {
  todos: { 7: todo },
  alerts: ['late'],
  todoById: todo
})

Memoizer exports

lruMemoize and weakMapMemoize are the memoizer exports used for custom configuration. weakMapMemoize uses argument identity and has an effectively unlimited cache. lruMemoize supports configurable cache and equality behavior.

For a selector-wide choice, configure memoize directly:

import assert from 'node:assert/strict'
import { createSelector, weakMapMemoize } from 'reselect'

const selectLength = createSelector(
  [(state: { items: unknown[] }) => state.items],
  items => items.length,
  { memoize: weakMapMemoize }
)

const state = { items: ['a', 'b', 'c'] }
assert.equal(selectLength(state), 3)
assert.equal(selectLength(state), 3)

Development checks

Development-only checks include inputStabilityCheck and identityFunctionCheck; the current documentation also lists cacheSizeCheck. Checks are disabled in production environments and default to running once.

Configure supported global checks with setGlobalDevModeChecks, or override checks per selector through devModeChecks:

import assert from 'node:assert/strict'
import { createSelector, setGlobalDevModeChecks } from 'reselect'

setGlobalDevModeChecks({ inputStabilityCheck: 'always' })
setGlobalDevModeChecks({ identityFunctionCheck: 'never' })

const selectTodoIds = createSelector(
  [(state: { todos: Array<{ id: number }> }) => state.todos],
  todos => todos.map(todo => todo.id),
  {
    devModeChecks: {
      inputStabilityCheck: 'always',
      identityFunctionCheck: 'never'
    }
  }
)

assert.deepEqual(selectTodoIds({ todos: [{ id: 1 }] }), [1])

cacheSizeCheck is configured only globally. A selector-level devModeChecks.cacheSizeCheck setting has no effect because that check runs inside weakMapMemoize.

v5 migration traps

  • Do not use the v4 names defaultMemoize or defaultEqualityCheck; they were renamed to lruMemoize and referenceEqualityCheck.
  • Do not assume the v4 cache-size-one default. v5 uses weakMapMemoize for both memoize and argsMemoize by default.
  • Use Selector and OutputSelector for selectors with additional parameters; ParametricSelector and OutputParametricSelector were removed.
  • TypeScript versions below 4.7 are unsupported.
  • The second createStructuredSelector overload was removed.
  • createSelector.withTypes<StateType>() is only available from 5.1.0 onward and is therefore not guaranteed across the entire ^5.0.0 range. Its documented inference limitation is that input selectors must be supplied as one array.

Not covered

This skill does not cover undocumented internals, exact cache-size or equality defaults beyond the v5 behavior described above, framework integrations, production build configuration, or APIs not shown in the supplied research. It also does not prescribe how a runner or application invokes selectors; Reselect itself exposes no required CLI or runner workflow in the researched surface.