{"id":43013665,"url":"https://github.com/lodado/react-namespace","last_synced_at":"2026-01-31T05:40:06.261Z","repository":{"id":263119673,"uuid":"889352680","full_name":"lodado/react-namespace","owner":"lodado","description":"Namespace Store for React is a simple and powerful state management library designed to solve issues with nested contexts in React applications. 🌟","archived":false,"fork":false,"pushed_at":"2025-01-22T06:45:34.000Z","size":721,"stargazers_count":2,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-24T10:44:10.265Z","etag":null,"topics":["atomic-design","context","design-systems","fsd","nested-context","react","scope","states","suspense"],"latest_commit_sha":null,"homepage":"https://github.com/lodado/react-namespace","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/lodado.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-11-16T06:31:23.000Z","updated_at":"2024-12-19T06:45:13.000Z","dependencies_parsed_at":"2024-11-16T10:28:29.412Z","dependency_job_id":"01a66f0b-64d8-42bb-b54f-e196857bde64","html_url":"https://github.com/lodado/react-namespace","commit_stats":null,"previous_names":["lodado/react-namespace"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/lodado/react-namespace","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lodado%2Freact-namespace","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lodado%2Freact-namespace/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lodado%2Freact-namespace/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lodado%2Freact-namespace/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lodado","download_url":"https://codeload.github.com/lodado/react-namespace/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lodado%2Freact-namespace/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28930585,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T04:05:25.756Z","status":"ssl_error","status_checked_at":"2026-01-31T04:02:35.005Z","response_time":128,"last_error":"SSL_read: 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":["atomic-design","context","design-systems","fsd","nested-context","react","scope","states","suspense"],"created_at":"2026-01-31T05:40:05.162Z","updated_at":"2026-01-31T05:40:06.243Z","avatar_url":"https://github.com/lodado.png","language":"TypeScript","readme":"\n# Namespace Store for React\n\n[![npm version](https://img.shields.io/npm/v/@lodado/react-namespace)](https://www.npmjs.com/package/@lodado/react-namespace)\n[![npm downloads](https://img.shields.io/npm/dt/@lodado/react-namespace)](https://www.npmjs.com/package/@lodado/react-namespace)\n\nNamespace Store for React is a simple and powerful state management library designed to solve issues with nested contexts in React applications. Inspired by Radix UI's scopeContext and createContext wrapper, it leverages the Proxy API to effectively handle both global and local state.\n\n![carbon (3) (1)](https://github.com/user-attachments/assets/0016707c-7d92-47f2-b6fc-35c9f8bb468e)\n\n![simplescreenrecorder-2024-12-12_20 23 30-ezgif com-video-to-gif-converter](https://github.com/user-attachments/assets/e6a9afcf-9454-40f4-816c-786b2b223b49)\n\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Getting Started](#getting-started---basic-usage)\n  - [Creating a Namespace Store](#creating-a-namespace-store)\n  - [Creating a Namespace Context](#creating-a-namespace-context)\n  - [Providing the Store](#providing-the-store)\n  - [Consuming the Store](#consuming-the-store)\n- [Scope](#scope)\n- [API Reference](#api-reference)\n  - [`createNamespaceContext`](#createnamespacecontext)\n  - [`createNamespaceScope`](#createnamespacescope)\n  - [`composeContextScopes`](#composecontextscopes)\n- [Examples](#example-codes)\n  - [Example codes](#example-codes)\n  - [Using Local Stores](#using-local-stores)\n  - [Namespaced Scopes](#namespaced-scopes)\n  - [Composing Scopes](#composing-scopes)\n- [License](#license)\n\n## Features\n\n- **Lightweight**: Minimal overhead added to your application.\n- **Namespaced State Management**: Isolate state within specific contexts or scopes.\n- **Flexible Store Options**: Supports both global and local stores.\n- **TypeScript Support**: Fully typed for better developer experience.\n- **Inspired by Radix UI**: Leverages concepts from Radix UI's `scopeContext` for modular component development.\n\n## Motivation\n\n\n\u003chttps://react.dev/reference/react/useContext#passing-data-deeply-into-the-tree\u003e\n\nWhen using React's Context API, the following issues can arise:\n\n- The entire tree wrapped by the context gets re-rendered.\n- Only the nearest parent context is accessible, making it difficult to manage when multiple contexts are nested.\n\nInspired by the concept of \"scope\" introduced by the Radix UI library ([Radix Context](https://github.com/radix-ui/primitives/tree/main/packages/react/context)), I developed this library to address these challenges.\n\n- Provides a more flexible and scalable approach to state management.\n- Reduces unnecessary re-renders.\n- Simplifies implementation for deeply nested components.\n\n### Main purpose\n\nThe main purpose of this library is not so much for global state management (although it can be used that way too!) but rather for managing state in a flexible, simple, and efficient manner when developing component-based applications, much like its name 'namespace' suggests.\n\nIt is recommended for use in the following cases:\n\n- Developing design system components (I use it with radix-ui)\n- Large and complex components such as features, widgets, and pages in the FSD architecture, or organisms in the atomic design pattern\n- Recursive structures like nested tabs, especially when there is a need to manipulate them mutually\n- When external components need to manipulate the state within a context\n\n## Installation\n\n```\nnpm install @lodado/namespace-core @lodado/react-namespace\n\n# or \n\nyarn add @lodado/namespace-core @lodado/react-namespace\n...etc\n```\n\n(TO-DO)\n\n## Getting Started - Basic Usage\n\n### Creating a Namespace Store\n\nFirst, you need to create a store that will hold your application's state. This store should extend the `NamespaceStore` provided by the library.\n\n```typescript\nimport { NamespaceStore } from '@lodado/namespace-core';\n\ninterface AppState {\n  user: {\n    name: string;\n    email: string;\n  };\n  theme: 'light' | 'dark';\n}\n\nclass AppStore extends NamespaceStore\u003cAppState\u003e {\n  constructor(initialState: AppState) {\n    super(initialState);\n  }\n\n  // Define actions to modify the state\n  setUser(user: AppState['user']) {\n    this.state.user = user;\n  }\n\n  toggleTheme() {\n    this.state.theme = this.state.theme === 'light' ? 'dark' : 'light';\n  }\n}\n\n// Create a global store instance\nconst globalStore = new AppStore({\n  user: {\n    name: 'John Doe',\n    email: '\u003cjohn.doe@example.com\u003e',\n  },\n  theme: 'light',\n});\n```\n\n### Creating a Namespace Context\n\nUse the `createNamespaceContext` function to create a context for your namespace store.\n\n```typescript\nimport { createNamespaceContext } from \"@lodado/react-namespace\";\n\nconst {\n  Provider: AppProvider,\n  useNamespaceStores,\n  useNamespaceAction,\n} = createNamespaceContext\u003cAppState, AppStore\u003e({\n  globalStore, // global store\n  // localStore, // store per provider\n});\n```\n\n### Providing the Store\n\nWrap your application or specific components with the `AppProvider` to provide the store context.\n\n```tsx\nimport React from 'react';\nimport { AppProvider } from './path-to-your-provider';\n\nfunction App() {\n  return (\n    \u003cAppProvider\u003e\n      \u003cYourComponent /\u003e\n    \u003c/AppProvider\u003e\n  );\n}\n\nexport default App;\n```\n\n### Consuming the Store\n\nUse the `useNamespaceStores` and `useNamespaceAction` hooks to access the state and actions within your components.\n\n```tsx\nimport React from 'react';\nimport { useNamespaceStores, useNamespaceAction } from './path-to-your-provider';\n\nfunction YourComponent() {\n  const { user } = useNamespaceStores((state) =\u003e {\n    return { user: state.user }\n  }});\n  const { setUser, toggleTheme } = useNamespaceAction();\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eWelcome, {user.name}\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e toggleTheme()}\u003e\n        Switch to {state.theme === 'light' ? 'dark' : 'light'} mode\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default YourComponent;\n```\n\nor you can just use useNamespaceStores\n\n```tsx\nimport React from 'react';\nimport { useNamespaceStores, useNamespaceAction } from './path-to-your-provider';\n\nfunction YourComponent() {\n  const { user, setUser, toggleTheme  } = useNamespaceStores((state) =\u003e {\n    return { user: state.user }\n  }}) \n  \n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eWelcome, {state.user.name}\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e toggleTheme()}\u003e\n        Switch to {state.theme === 'light' ? 'dark' : 'light'} mode\n      \u003c/button\u003e\n    \u003c/div\u003e\n  );\n}\n\nexport default YourComponent;\n```\n\n# Scope\n\nThe concept of \"scope\" overcomes React Context's limitations, such as the challenges of \nmanaging nested contexts and the overhead of re-rendering entire trees.\n\n---\n\n### Example Code\n\nBelow is an example that demonstrates how to create and use **scoped state** with `@lodado/react-namespace`.\n\n#### 1. Define Stores for Scoped State\n\n```tsx\nimport { NamespaceStore } from '@lodado/namespace-core';\n\n// Counter store for managing count\nclass Counter extends NamespaceStore\u003c{ count: number }\u003e {\n  constructor(initialCount = 0) {\n    super({ count: initialCount });\n  }\n\n  increment() {\n    this.state.count += 1;\n  }\n\n  decrement() {\n    this.state.count -= 1;\n  }\n}\n\n// Text store for managing text\nclass Text extends NamespaceStore\u003c{ text: string }\u003e {\n  constructor() {\n    super({ text: 'test' });\n  }\n\n  updateText() {\n    this.state.text = 'updated';\n  }\n}\n```\n\n---\n\n#### 2. Create Scopes and Providers\n\nScopes allow you to isolate state for different contexts. In this example, a `Dialog` scope and an `AlertDialog` scope are created.\n\n```tsx\nimport { createNamespaceScope, Scope } from '@lodado/react-namespace';\n\n// Create a Dialog scope\nconst [createDialogContext, createDialogScope] = createNamespaceScope('Dialog');\n\nconst { Provider: DialogProvider, useNamespaceStores: useDialogNamespaceStore } = createDialogContext('Dialog', {\n  localStore: () =\u003e new Counter(),\n});\n\n// Create an AlertDialog scope, extending Dialog scope\nconst [createAlertDialogProvider, createAlertDialogScope] = createNamespaceScope('AlertDialog', [createDialogScope]);\n\nconst { Provider: AlertDialogProvider, useNamespaceStores: useAlertDialogNamespaceStore } = createAlertDialogProvider('AlertDialogContext', {\n  localStore: () =\u003e new Text(),\n});\n```\n\n---\n\n#### 3. Use Scoped State in Components\n\nUsing `useNamespaceStores`, you can access state from specific scopes.\n\n```tsx\nconst DialogContent = ({ scope, scope2 }: { scope: Scope\u003cany\u003e; scope2: Scope\u003cany\u003e }) =\u003e {\n\n  const { count } = useDialogNamespaceStore((state) =\u003e ({ count: state.count }), scope);\n\n  const { text } = useAlertDialogNamespaceStore((state) =\u003e ({ text: state.text }), scope);\n\n  const { increment } = useDialogNamespaceStore(() =\u003e ({}), scope2);\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={increment}\u003eClick!\u003c/button\u003e\n      \u003cdiv\u003e\n        Content: {count} - {text}\n      \u003c/div\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n---\n\n#### 4. Combine Scopes in Your Application\n\nYou can nest providers with different scopes to isolate and manage state efficiently.\n\n```tsx\nexport const ScopeExample = () =\u003e {\n  const scope1 = createAlertDialogScope()({});\n  const scope2 = createAlertDialogScope()({});\n\n  return (\n    \u003cAlertDialogProvider scope={scope1.__scopeAlertDialog}\u003e\n      \u003cAlertDialogProvider scope={scope2.__scopeAlertDialog}\u003e\n        \u003cDialogProvider scope={scope2.__scopeAlertDialog}\u003e\n          \u003cDialogProvider scope={scope1.__scopeAlertDialog}\u003e\n            \u003cDialogContent scope={scope1.__scopeAlertDialog} scope2={scope2.__scopeAlertDialog} /\u003e\n            \u003cDialogContent scope={scope2.__scopeAlertDialog} scope2={scope1.__scopeAlertDialog} /\u003e\n          \u003c/DialogProvider\u003e\n        \u003c/DialogProvider\u003e\n      \u003c/AlertDialogProvider\u003e\n    \u003c/AlertDialogProvider\u003e\n  );\n};\n```\n\n---\n\nThis example highlights how **scoped state** allows you to create isolated, modular, and reusable contexts for state management, particularly in scenarios with nested or complex components.\n\n## API Reference\n\n### `createNamespaceContext`\n\nCreates a namespace context for managing state and actions within a specific namespace.\n\n#### Type Definitions\n\n```typescript\nfunction createNamespaceContext\u003c\n  State extends Record\u003cstring | symbol, any\u003e,\n  StoreType extends NamespaceStore\u003cState\u003e,\n\u003e(options: StoreOption\u003cState, StoreType\u003e): {\n  readonly Context: React.Context\u003cStoreType | undefined\u003e;\n  readonly Provider: React.FC\u003c{\n    overwriteStore?: (() =\u003e StoreType) | StoreType;\n    children: React.ReactNode;\n  }\u003e;\n  readonly store: StoreType | undefined;\n  readonly useNamespaceStores: () =\u003e { state: State };\n  readonly useNamespaceAction: () =\u003e StoreType; // context functions \n  readonly useNamespaceContext: () =\u003e StoreType // \"context\"\n};\n```\n\n#### Parameters\n\n- `options`: An object containing the following properties:\n  - `globalStore`: An optional global store instance or a function that returns one.\n  - `localStore`: An optional local store instance or a function that returns one.\n\n#### Returns\n\nAn object containing:\n\n- `Context`: The React context for the namespace.\n- `Provider`: A provider component to wrap your application or components.\n- `store`: The global store instance.\n- `useNamespaceStores`: A hook to access the state.\n- `useNamespaceAction`: A hook to access the actions.\n\n#### example code\n\n```jsx\n\nimport { NamespaceStore } from '@lodado/namespace-core'\nimport { createNamespaceContext } from '@lodado/react-namespace'\n\nclass Counter extends NamespaceStore\u003c{ count: number; text: string }\u003e {\n  constructor() {\n    super({ count: 0, text: 'teest' })\n  }\n\n  increment() {\n    this.state.count += 1\n  }\n\n  decrement() {\n    this.state.count -= 1\n  }\n\n  updateText() {\n    this.state.text = 'updated'\n  }\n}\nlet cnt = 0\n\nconst { Provider: ExampleProvider, useNamespaceStores } = createNamespaceContext({\n  globalStore: new Counter(),\n})\n\n```\n\n### `createNamespaceScope`\n\nCreates a namespace scope for managing state and actions within a specific namespace.\n\n#### Type Definitions\n\n```typescript\nfunction createNamespaceScope(\n  scopeName: string,\n  createContextScopeDeps: CreateScope[] = [],\n): readonly [\n  typeof createScopeContext,\n  ReturnType\u003ctypeof composeContextScopes\u003e,\n];\n```\n\n#### Parameters\n\n- `scopeName`: The name of the namespace scope.\n- `createContextScopeDeps`: An array of dependencies for creating the context scope.\n\n#### Returns\n\nA tuple containing:\n\n- `createScopeContext`: Function to create a context for a namespace store.\n- `composeContextScopes`: Function to compose multiple context scopes.\n \n### `composeContextScopes`\n\nComposes multiple context scopes into a single scope.\n\n#### Type Definitions\n\n```typescript\nfunction composeContextScopes(...scopes: CreateScope[]): CreateScope;\n```\n\n#### Parameters\n\n- `scopes`: A list of `CreateScope` functions to compose.\n\n#### Returns\n\n- `createScope`: A function that creates a composed scope.\n\n## Examples\n\n### Example codes \n\n---\n\n#### Table Example codes \n[https://github.com/lodado/react-namespace/blob/main/apps/docs/stories/scope/table/App.tsx](https://github.com/lodado/react-namespace/tree/main/apps/docs/stories/scope/table)\n\n#### TicTactoe\n[https://github.com/lodado/react-namespace/tree/main/apps/docs/stories/scope/tictactoe \n](https://github.com/lodado/react-namespace/tree/main/apps/docs/stories/scope/tictactoe)\n\n---\n\n\n### Using Local Stores\n\nYou can also provide a local store specific to a component or a subtree.\n\n```typescript\nconst localStore = new AppStore({\n  user: {\n    name: 'Jane Doe',\n    email: '\u003cjane.doe@example.com\u003e',\n  },\n  theme: 'dark',\n});\n\n// In your component\n\u003cAppProvider overwriteStore={localStore}\u003e\n  \u003cYourComponent /\u003e\n\u003c/AppProvider\u003e;\n```\n\n### Namespaced Scopes\n\nIf you're building a library of components and want to avoid conflicts, you can create a namespaced scope.\n\n```typescript\nimport { createNamespaceScope } from \"@lodado/react-namespace\";\n\nconst [createScopeContext, createScope] = createNamespaceScope('MyComponent');\n\nconst {\n  Provider: MyComponentProvider,\n  useNamespaceStores,\n} = createScopeContext\u003cAppStore\u003e('MyComponent', { globalStore });\n\n// Use in your component\n\u003cMyComponentProvider\u003e\n  \u003cYourComponent /\u003e\n\u003c/MyComponentProvider\u003e;\n```\n\n### Composing Scopes\n\nCompose multiple scopes to create isolated contexts.\n\n```typescript\nconst [createScopeContextA, createScopeA] = createNamespaceScope('ScopeA');\nconst [createScopeContextB, createScopeB] = createNamespaceScope('ScopeB');\n\nconst composedScope = composeContextScopes(createScopeA, createScopeB);\n\n// Now you can use the composed scope in your providers and hooks\nconst [createScopeContext, createScope] = createNamespaceScope('ComposedScope', [composedScope]);\n\nconst {\n  Provider: ComposedProvider,\n  useNamespaceStores,\n  useNamespaceAction,\n} = createScopeContext\u003cAppStore\u003e('ComposedScope', { globalStore });\n\n// Use in your component\n\u003cComposedProvider\u003e\n  \u003cYourComponent /\u003e\n\u003c/ComposedProvider\u003e;\n```\n\n### reset State\n\nyou can reset states with reset function in useNamespaceAction or useNamespaceStores\n\n```jsx\nconst TestComponent = () =\u003e {\n  const { count } = useNamespaceStores((state) =\u003e ({ count: state.count }))\n  const { increment, decrement, reset } = useNamespaceAction()\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton type=\"button\" data-testid=\"reset-button\" onClick={reset}\u003e\n        Reset\n      \u003c/button\u003e\n      \u003cbutton type=\"button\" data-testid=\"increment-button\" onClick={increment}\u003e\n        Increment\n      \u003c/button\u003e\n      \u003cbutton type=\"button\" data-testid=\"decrement-button\" onClick={decrement}\u003e\n        Decrement\n      \u003c/button\u003e\n    \u003c/div\u003e\n  )\n}\n```\n\n### use \"Context\" value\n\nyou can use literally \"context\" class instance via useNamespaceContext\n\n```jsx\n\n  const TestComponent = () =\u003e {\n    const context = useNamespaceContext()\n    ...\n  }\n```\n\n## License\n\nMIT License\n\n---\n\nThis library simplifies state management in React applications by providing a structured and scalable way to handle state across different components and scopes. Whether you're building a small application or a large-scale project, this namespace store can help you maintain clean and maintainable code.\n\nFeel free to contribute to the project by submitting issues or pull requests on the GitHub repository.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flodado%2Freact-namespace","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flodado%2Freact-namespace","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flodado%2Freact-namespace/lists"}