{"id":11379,"library":"nanostores","title":"Nano Stores","description":"Nano Stores is a lightweight and performant state manager designed for a wide range of JavaScript frameworks including React, Preact, Vue, Svelte, and vanilla JS. Currently stable at version 1.3.0, the library maintains an active release cadence, frequently introducing new features and improvements. Its core philosophy revolves around using many atomic, tree-shakable stores and direct manipulation, which contributes to its incredibly small footprint (294-831 bytes minified and brotlied) and zero external dependencies. Key differentiators include its focus on moving business logic out of components into dedicated stores, optimizing for speed by avoiding unnecessary selector calls, and providing first-class TypeScript support. This architecture ensures excellent tree-shaking, only bundling the stores actually used in a given chunk.","status":"active","version":"1.3.0","language":"javascript","source_language":"en","source_url":"https://github.com/nanostores/nanostores","tags":["javascript","preact","react","react native","state","state manager","store","svelte","vue","typescript"],"install":[{"cmd":"npm install nanostores","lang":"bash","label":"npm"},{"cmd":"yarn add nanostores","lang":"bash","label":"yarn"},{"cmd":"pnpm add nanostores","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"The primary function for creating atomic stores. Nano Stores is ESM-first, so CommonJS `require()` is not supported directly without a transpilation layer.","wrong":"const { atom } = require('nanostores')","symbol":"atom","correct":"import { atom } from 'nanostores'"},{"note":"Used to derive state from one or more existing stores. Asynchronous `computed` was deprecated in v1.2.0; use `@nanostores/async` for async derivations.","wrong":"import { computed as asyncComputed } from 'nanostores'","symbol":"computed","correct":"import { computed } from 'nanostores'"},{"note":"This is a framework-specific hook, exemplified here for React. Equivalent hooks for Vue, Svelte, etc., are available in their respective `@nanostores/<framework>` packages.","wrong":"import { useStore } from 'nanostores'","symbol":"useStore","correct":"import { useStore } from '@nanostores/react'"}],"quickstart":{"code":"interface Task {\n  id: string;\n  text: string;\n  completed: boolean;\n}\n\nimport { atom, computed } from 'nanostores';\n\n// 1. Create an atomic store using `atom`\nexport const $tasks = atom<Task[]>([]);\n\n// 2. Define actions to manipulate the store\nexport function addTask(text: string) {\n  const newTask: Task = {\n    id: String(Date.now()),\n    text,\n    completed: false\n  };\n  $tasks.set([...$tasks.get(), newTask]);\n  console.log(`Added task: \"${text}\"`);\n}\n\nexport function toggleTask(id: string) {\n  $tasks.set($tasks.get().map(task =>\n    task.id === id ? { ...task, completed: !task.completed } : task\n  ));\n  console.log(`Toggled task with ID: ${id}`);\n}\n\n// 3. Create a derived store using `computed`\nexport const $pendingTasksCount = computed($tasks, tasks =>\n  tasks.filter(task => !task.completed).length\n);\n\n// 4. Subscribe to store changes\nconsole.log('--- Initial State ---');\nconsole.log('Tasks:', $tasks.get());\nconsole.log('Pending count:', $pendingTasksCount.get());\n\nconst unsubscribeTasks = $tasks.listen(currentTasks => {\n  console.log('\\n--- Tasks Updated ---');\n  console.log('Current tasks:', currentTasks.map(t => `${t.text} (${t.completed ? 'Done' : 'Pending'})`).join(', '));\n});\n\nconst unsubscribePendingCount = $pendingTasksCount.listen(count => {\n  console.log('Current pending tasks count:', count);\n});\n\n// 5. Trigger actions to see state changes\naddTask('Learn Nano Stores');\naddTask('Build a cool app');\ntoggleTask($tasks.get()[0]?.id || '');\n\nsetTimeout(() => {\n  addTask('Review documentation');\n  toggleTask($tasks.get()[1]?.id || '');\n  console.log('\\n--- Final State after Timeout ---');\n  console.log('Tasks:', $tasks.get().map(t => `${t.text} (${t.completed ? 'Done' : 'Pending'})`).join(', '));\n  console.log('Pending count:', $pendingTasksCount.get());\n\n  // Clean up subscriptions (important in real apps)\n  unsubscribeTasks();\n  unsubscribePendingCount();\n}, 200);\n","lang":"typescript","description":"This example demonstrates creating an atomic store with `atom`, defining actions to modify it, deriving state with `computed`, and subscribing to changes using `listen` to observe state updates."},"warnings":[{"fix":"Upgrade your Node.js environment to version 20.0.0 or newer (or 22.0.0 for the latest recommended). The `engines` field in `package.json` specifies `^20.0.0 || >=22.0.0`.","message":"Node.js v18.x support was removed in Nano Stores v1.0.0. Projects using older Node.js versions will encounter runtime errors or installation failures.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"For asynchronous computed stores, migrate to the `@nanostores/async` package. Update your imports and logic to use the dedicated async utilities from this new package.","message":"The async `computed` functionality within the main `nanostores` package was deprecated in favor of a separate `@nanostores/async` package.","severity":"deprecated","affected_versions":">=1.2.0"},{"fix":"If you are using deep map stores, migrate to the `@nanostores/deepmap` package. Update your imports and code to use the `deepmap` utility from this external package.","message":"The `deepmap()` utility was deprecated in favor of a separate `@nanostores/deepmap` package.","severity":"deprecated","affected_versions":">=1.1.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Use ES Module `import` syntax (`import { atom } from 'nanostores'`). Ensure your project is configured for ESM (e.g., by setting `\"type\": \"module\"` in `package.json` or using a bundler like Webpack/Rollup/Vite).","cause":"Attempting to use `require()` to import Nano Stores, which is distributed as an ES Module (ESM).","error":"ERR_REQUIRE_ESM ... require() of ES Module ... Not supported"},{"fix":"Verify that the variable `$store` is indeed a store created by `atom()` or `computed()`. Also, ensure you are importing core store functions (e.g., `atom`, `computed`) from `nanostores` and framework-specific utilities (e.g., `useStore`) from their respective packages (e.g., `@nanostores/react`).","cause":"This error often indicates that you are trying to call a store method (like `.subscribe()`, `.get()`, or `.set()`) on a variable that is not a valid Nano Stores store object, or you've incorrectly imported a framework-specific utility instead of a core store.","error":"TypeError: $store.subscribe is not a function"},{"fix":"Upgrade your Node.js version to `20.0.0` or `22.0.0` (or newer) to meet the minimum engine requirements for Nano Stores v1.0.0 and above.","cause":"You are running a Nano Stores version 1.0.0 or higher on an unsupported Node.js v18.x environment.","error":"Error: Node.js v18.x is no longer supported."}],"ecosystem":"npm"}