use-context-selector
A userland implementation of useContextSelector that stops React Context updates from re-rendering every consumer.
Repository Health
Technical Analysis
use-context-selector solves a well-known React Context performance problem: any component that calls useContext re-renders whenever the context value changes, even if it only reads a small slice of that value. This library implements the community-proposed useContextSelector API in userland, letting components subscribe to a derived slice of context state and only re-render when that specific slice actually changes.
Under the hood it wraps React’s Context with a version-tracked listener system built on useReducer’s “cheat mode” and a custom provider, so it behaves like ordinary Context for consumers that don’t opt into selectors, while giving selector-based consumers fine-grained bail-out behavior. It also ships useContextUpdate for coordinating updates during concurrent rendering and a BridgeProvider/useBridgeValue pair for forwarding context across separate React roots (e.g. portals or multi-root apps).
What You Get
- A drop-in createContext/useContextSelector pair that mirrors React’s Context API but adds fine-grained subscriptions
- A useContext hook for reading the full context value with the same underlying performance model
- useContextUpdate for wrapping state updates that need to behave correctly under concurrent rendering
- BridgeProvider and useBridgeValue for forwarding a context value across separate React renderer roots
Common Use Cases
- Avoiding cascading re-renders in large component trees that share one Context provider for global UI or app state
- Building a lightweight state container without pulling in Redux, Zustand, or another external state library
- Powering derived-state libraries like react-tracked and use-atom that need selector semantics on top of Context
- Bridging context values into portals or secondary React roots via BridgeProvider
Under The Hood
Architecture The entire library lives in one file, src/index.ts (~340 lines) — there is no layered module structure. createContext wraps React’s native createContext and replaces its Provider with a createProvider() closure that tracks a valueRef/versionRef/listeners Set via useRef, exposing update() through a symbol-keyed value (CONTEXT_VALUE) stored on the context so consumers can read version/listener state without themselves re-rendering. useContextSelector reads that context value, runs the caller’s selector, and drives a useReducer whose reducer compares an incoming action’s version against its closed-over version to decide whether to bail out (via Object.is) or accept a new [value, selected] tuple; components register their dispatch as a listener inside a useIsomorphicLayoutEffect. The whole mechanism hinges on one closure (contextValue.current) and the invariant that listeners stay in sync with mounted components — a small, tightly-coupled but deliberately designed pub-sub layer over Context.
Tech Stack
Pure TypeScript with zero runtime dependencies beyond its peers: react (>=18) and scheduler (>=0.19), the latter used for unstable_runWithPriority/unstable_NormalPriority to schedule listener notifications at normal priority, with a graceful fallback for renderers like Preact that lack it. The build produces dual ESM/CJS output via two separate tsconfig targets (compile:esm, compile:cjs). Tooling is modern and lean: vitest with @testing-library/react and happy-dom for tests, an ESLint flat config combining typescript-eslint, import, jsx-a11y, react and react-hooks plugins, Prettier for formatting, and the documentation package to mechanically regenerate the README’s API section from JSDoc comments. Three Vite-served example apps (counter, person, suspense) double as living documentation.
Code Quality
Tests specifically target known React Context failure modes — tearing, stale props, concurrent-mode behavior, and context bridging — across six spec files plus committed snapshots, which is a strong signal for a library this concurrency-sensitive. Source code is fully typed with generics on selectors and context values, includes development-mode runtime assertions that throw on misuse (guarded by NODE_ENV checks), and gates pnpm test on formatting, linting, type-checking (including the examples’ types) and the spec suite together. The one silently-swallowing catch block is explicitly commented as an intentional tradeoff for stale-props handling rather than an oversight, and CI runs via a GitHub Actions workflow referenced in the README badge.
API Design The public surface is intentionally tiny and mirrors React’s own Context API almost one-to-one — createContext, Provider, useContext — plus useContextSelector, useContextUpdate, and the Bridge pair, so adoption is mostly a matter of swapping the import source and adding selector functions. Every exported function carries a JSDoc block with a runnable @example that is mechanically synced into the README, preventing docs from drifting from the code. The real DX cost is conceptual rather than syntactic: selectors must return referentially stable results and children must be memoized to fully stop propagation, both called out explicitly in a “Limitations” section instead of left as a silent gotcha.
Used by 7 apps in this directory
Dify
No Code Platforms · AI Development · Developer Tools
Visual LLM workflow platform with RAG pipelines, agent capabilities, and model management for building production AI applications.
FastGPT
AI Agents · AI Development
Build, debug, and deploy knowledge-based AI agents with a visual workflow editor, RAG retrieval, and support for any OpenAI-compatible LLM.
Lightdash
Analytics · Data Engineering
The open-source Looker alternative that turns your dbt project's metrics and dimensions into governed, self-serve charts and dashboards — no license key required.
NocoBase
No Code Platforms · Low Code Platforms
Open-source AI + no-code platform that lets coding agents and people collaborate to build business systems fast on proven infrastructure.
Payload CMS
Developer Tools · Blogging · CMS
The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.
strapi
CMS
Open-source headless CMS that auto-generates REST and GraphQL APIs from your content models, with a fully customizable admin panel you control.
Tolgee
Developer Tools
In-context localization platform that lets developers and translators edit app strings directly in the running application, with AI-powered machine translation and framework SDKs for React, Angular, Vue, and Svelte.