# Why

Why — Legend State documentation.

Source: https://legend.so/state/v2/intro/why/

Legend State v2 documentation. **Archived version.** [Read the current documentation.](https://legend.so/state/v3/intro/introduction/)

Legend-State is an evolution of the state system we've been using internally in [Legend](https://www.legendapp.com/) since 2015 and in [Bravely](https://www.bravely.io/) since 2020. It needs to be extremely fast because Legend users have documents with hundreds of thousands of items. We recently rewrote it with modern browser features, optimizing for both developer experience and best possible performance / memory usage. Comparing to other state libraries, we think you'll prefer Legend-State for these reasons:

## [⚡️ Tiny and FAST](https://legend.so/state/v2/intro/why/#%EF%B8%8F-tiny-and-fast)

Legend-State is the [fastest React state library](https://legend.so/state/v2/intro/fast), designed to be as efficient as possible. It does very little extra work and minimizes renders by only re-rendering components when their observables change.

## [😌 Feels natural](https://legend.so/state/v2/intro/why/#-feels-natural)

Working with observables is as simple as `get()` and `set()` - they work as you'd expect, and the observable functions are right there on the prototype.

```jsx
const state$ = observable({ value: 1 });
state$.value.get();
state$.value.set(2);

// Tracks automatically and runs on every change
observe(() => {
  console.log(state$.value.get());
});
```

## [🔥 Fine-grained reactivity](https://legend.so/state/v2/intro/why/#-fine-grained-reactivity)

Using features like [Memo](https://legend.so/state/v2/react/fine-grained-reactivity#memo) it's easy to isolate renders to the smallest possible change.

For isolating a group of elements or computations, Legend-State has [built-in helpers](https://legend.so/state/v2/react/fine-grained-reactivity) to easily extract children so that their changes do not affect the parent. This keeps large parent components from rendering often just because their children change.

## [👷 Does not hack React internals](https://legend.so/state/v2/intro/why/#-does-not-hack-react-internals)

Some libraries hack up React internals to make signals and fine-grained reactivity work, which often doesn't work on all platforms and may break if React internals change.

Legend-State does everything above-board using hooks, with all React functionality built on top of [useSelector](https://legend.so/state/v2/react/react-api#useselector), which just uses `useSyncExternalStore`. Check [the source](https://github.com/LegendApp/legend-state/blob/main/src/react/useSelector.ts) to see the lack of hackery.

## [🤷‍♀️ Unopinionated](https://legend.so/state/v2/intro/why/#%EF%B8%8F-unopinionated)

Some state libraries are for global state while some want state to reside within React. Some enourage individual atoms and others are for large global stores. Some have "actions" and "reducers" and others require immutability. But you can use Legend-State any way you want.

-   **Global state or local state in React**: Up to you 🤷‍♀️
-   **Individual atoms or one store**: Up to you 🤷‍♀️
-   **Modify directly or in actions/reducers**: Up to you 🤷‍♀️

See [Patterns](https://legend.so/state/v2/guides/patterns) for more examples of different ways to use Legend-State.

## [💾 Persistence built in](https://legend.so/state/v2/intro/why/#-persistence-built-in)

> There are only two hard things in Computer Science: cache invalidation and naming things. - Phil Karlton

We don't want developers to have to worry about persisting and syncing state, because it's often very complicated and error-prone. So we've built [persistence](https://legend.so/state/v2/guides/persistence) plugins using Legend-State's listeners, with extensive tests to make sure it's absolutely correct.

It currently includes plugins for local persistence with Local Storage and IndexedDB on web and [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) in React Native, and remote sync plugins for Firebase Realtime Database, TanStack Query, and `fetch`.

```js
import { ObservablePersistLocalStorage } from '@legendapp/state/persist-plugins/local-storage'
import { ObservablePersistFirebase } from "@legendapp/state/persist-plugins/firebase"
import { persistObservable } from '@legendapp/state/persist'
import { observable } from '@legendapp/state'

const state$ = observable({ store: { bigObject: { ... } } })

// Persist this observable
persistObservable(state$, {
    pluginLocal: ObservablePersistLocalStorage,
    local: 'store',
    pluginRemote: ObservablePersistFirebase,
    remote: {
        firebase: {
            refPath: (uid) => `/users/${uid}/`,
            requireAuth: true,
        },
    }
})
```

## [🔫 It's safe from footguns](https://legend.so/state/v2/intro/why/#-its-safe-from-footguns)

Observables prevent direct assignment, favoring more purposeful `set` and `assign` functions instead. Read more in [safety](https://legend.so/state/v2/usage/observable#safety).

[View Markdown](https://legend.so/state/v2/intro/why.md)[Report a documentation correction](https://github.com/LegendApp/legend-docs/issues/new?title=Docs%3A+Why&body=Page%3A+https%3A%2F%2Flegend.so%2Fstate%2Fv2%2Fintro%2Fwhy%0A%0AWhat+is+incorrect+or+missing%3F%0A%0AExpected+behavior+or+supporting+source%3A%0A)
