> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/sveltejs/svelte/llms.txt
> Use this file to discover all available pages before exploring further.

# $state

> Create reactive state in Svelte with the $state rune

The `$state` rune allows you to create *reactive state*, which means that your UI *reacts* when it changes.

```svelte theme={null}
<script>
	let count = $state(0);
</script>

<button onclick={() => count++}>
	clicks: {count}
</button>
```

Unlike other frameworks you may have encountered, there is no API for interacting with state — `count` is just a number, rather than an object or a function, and you can update it like you would update any other variable.

## Signature

```ts theme={null}
function $state<T>(initial: T): T;
function $state<T>(): T | undefined;
```

<ParamField path="initial" type="T" optional>
  The initial value for the state. If not provided, the state will be `undefined`.
</ParamField>

## Deep state

If `$state` is used with an array or a simple object, the result is a deeply reactive *state proxy*. [Proxies](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy) allow Svelte to run code when you read or write properties, including via methods like `array.push(...)`, triggering granular updates.

State is proxified recursively until Svelte finds something other than an array or simple object (like a class or an object created with `Object.create`):

```js theme={null}
let todos = $state([
	{
		done: false,
		text: 'add more todos'
	}
]);
```

Modifying an individual todo's property will trigger updates to anything in your UI that depends on that specific property:

```js theme={null}
todos[0].done = !todos[0].done;
```

If you push a new object to the array, it will also be proxified:

```js theme={null}
todos.push({
	done: false,
	text: 'eat lunch'
});
```

<Note>
  When you update properties of proxies, the original object is *not* mutated.
</Note>

<Warning>
  Note that if you destructure a reactive value, the references are not reactive — as in normal JavaScript, they are evaluated at the point of destructuring.
</Warning>

```js theme={null}
let { done, text } = todos[0];

// this will not affect the value of `done`
todos[0].done = !todos[0].done;
```

## Classes

Class instances are not proxied. Instead, you can use `$state` in class fields (whether public or private), or as the first assignment to a property immediately inside the `constructor`:

```js theme={null}
class Todo {
	done = $state(false);

	constructor(text) {
		this.text = $state(text);
	}

	reset() {
		this.text = '';
		this.done = false;
	}
}
```

<Note>
  The compiler transforms `done` and `text` into `get`/`set` methods on the class prototype referencing private fields. This means the properties are not enumerable.
</Note>

## \$state.raw

```ts theme={null}
function raw<T>(initial: T): T;
function raw<T>(): T | undefined;
```

In cases where you don't want objects and arrays to be deeply reactive you can use `$state.raw`.

State declared with `$state.raw` cannot be mutated; it can only be *reassigned*:

```js theme={null}
let person = $state.raw({
	name: 'Heraclitus',
	age: 49
});

// this will have no effect
person.age += 1;

// this will work, because we're creating a new person
person = {
	name: 'Heraclitus',
	age: 50
};
```

This can improve performance with large arrays and objects that you weren't planning to mutate anyway, since it avoids the cost of making them reactive. Note that raw state can *contain* reactive state (for example, a raw array of reactive objects).

## \$state.snapshot

```ts theme={null}
function snapshot<T>(state: T): Snapshot<T>;
```

To take a static snapshot of a deeply reactive `$state` proxy, use `$state.snapshot`:

```svelte theme={null}
<script>
	let counter = $state({ count: 0 });

	function onclick() {
		// Will log `{ count: ... }` rather than `Proxy { ... }`
		console.log($state.snapshot(counter));
	}
</script>
```

This is handy when you want to pass some state to an external library or API that doesn't expect a proxy, such as `structuredClone`.

## \$state.eager

```ts theme={null}
function eager<T>(value: T): T;
```

When state changes, it may not be reflected in the UI immediately if it is used by an `await` expression, because updates are synchronized.

In some cases, you may want to update the UI as soon as the state changes. For example, you might want to update a navigation bar when the user clicks on a link:

```svelte theme={null}
<nav>
	<a href="/" aria-current={$state.eager(pathname) === '/' ? 'page' : null}>home</a>
	<a href="/about" aria-current={$state.eager(pathname) === '/about' ? 'page' : null}>about</a>
</nav>
```

<Warning>
  Use this feature sparingly, and only to provide feedback in response to user action — in general, allowing Svelte to coordinate updates will provide a better user experience.
</Warning>

## Sharing state across modules

You can declare state in `.svelte.js` and `.svelte.ts` files, but you can only *export* that state if it's not directly reassigned.

You have two options:

**Option 1: Don't reassign it**

```js theme={null}
// This is allowed — since we're updating
// `counter.count` rather than `counter`,
// Svelte doesn't wrap it in `$.state`
export const counter = $state({
	count: 0
});

export function increment() {
	counter.count += 1;
}
```

**Option 2: Don't directly export it**

```js theme={null}
let count = $state(0);

export function getCount() {
	return count;
}

export function increment() {
	count += 1;
}
```
