# React quick start

## Prerequisites

Use React 18 or later and TypeScript 4.5 or later. Zustand 5.0.15 requires React `>=18.0.0` and TypeScript 4.5 or later for its published types. The package requires Node.js `>=12.20.0`.

## Install Zustand

In your React project, run:

```bash
npm install zustand
```

## Connect a typed store to React

Use a store when several components need the same state or when you want the update logic beside the state it changes. This example creates a typed store, selects its state with [`useStore`](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/zustand#usestore), and mounts a component that toggles the displayed value.

1. Create the store. [`createStore`](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/zustand#createstore) gives you a store API that can be used outside React and passed to `useStore`.

```ts title="src/store.ts"
import { createStore } from 'zustand/vanilla'

type CounterStore = {
  enabled: boolean
  toggle: () => void
}

export const counterStore = createStore<CounterStore>((set, get) => ({
  enabled: false,
  toggle: () => set({ enabled: !get().enabled }),
}))
```

2. Select the state and action in a component. Each selector supplies one value from the store to the component.

```tsx title="src/App.tsx"
import { useStore } from 'zustand'

import { counterStore } from './store'

export function App() {
  const enabled = useStore(counterStore, (state) => state.enabled)
  const toggle = useStore(counterStore, (state) => state.toggle)

  return (
    <main>
      <p>Feature is {enabled ? 'enabled' : 'disabled'}</p>
      <button type="button" onClick={toggle}>
        Toggle feature
      </button>
    </main>
  )
}
```

3. Mount the component in the browser.

```tsx title="src/main.tsx"
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import { App } from './App'

const rootElement = document.getElementById('root')

if (rootElement === null) {
  throw new Error('Root element not found')
}

createRoot(rootElement).render(
  <StrictMode>
    <App />
  </StrictMode>,
)
```

The mounted page initially shows `Feature is disabled`. Clicking **Toggle feature** changes it to `Feature is enabled`; clicking again changes it back. Keep the store outside the component so React re-renders from the same store instance instead of creating a new store on each render.

## Watch out for

- Select individual values or actions when possible. A selector that creates a new reference on every render needs the approach described in [Selectors and rendering](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/selectors-and-rendering).
- Do not use a module-level global store for request-specific state in server-rendered applications. See [Handle server-rendered stores](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/handle-server-rendered-stores).

## Where to go next

- [How Zustand works](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/how-zustand-works) explains the store, immutable updates, selectors, actions, and vanilla stores.
- [Typed store patterns](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/typed-store-patterns) develops the TypeScript patterns used by larger stores.
- [Selectors and rendering](https://bench-zustand-56.atloria.app/p/bench-zustand-56-D8Xr4XerWj/developer/selectors-and-rendering) explains selection and render behavior, including stable outputs for computed selections.

Try the authors' [live demo](https://zustand-demo.pmnd.rs/) to see a mounted Zustand application.
