> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Browser storage APIs for extensions

> Persist settings and runtime state with browser storage APIs. Covers local, sync, and session storage and their impact on service worker reliability.

Extension.js does not replace or wrap browser storage APIs; it only compiles your code that calls them. The choice of storage area still matters. It shapes service-worker reliability, cross-browser consistency, and future data-structure changes.

## Choose the right storage area

| Storage area      | Use when                                         | Notes                                     |
| ----------------- | ------------------------------------------------ | ----------------------------------------- |
| `storage.local`   | durable extension state on one device            | best default for most extension data      |
| `storage.sync`    | small user preferences across signed-in browsers | quota-sensitive and slower than local     |
| `storage.session` | short-lived session state                        | useful for ephemeral runtime coordination |
| `storage.managed` | enterprise-managed policy values                 | schema-driven, read-only to the extension |

## Recommended defaults

* Use `storage.local` for feature state, caches, and durable settings.
* Use `storage.sync` only for small, user-meaningful preferences.
* Use `storage.session` for state that should not survive a full browser restart.
* Treat `storage.managed` as a separate enterprise path, not your general settings mechanism.

## Service-worker-friendly patterns

Manifest V3 (MV3) background service workers can stop and restart between events, so do not rely on in-memory state alone.

* Restore critical state from storage on demand.
* Cache in memory only as an optimization.
* Keep startup work small so event handling stays responsive.
* Persist versioned settings changes rather than assuming the background script stays running indefinitely.

## Example settings module

```ts theme={null}
const SETTINGS_KEY = "settings";

export async function getSettings() {
  const result = await chrome.storage.local.get(SETTINGS_KEY);
  return result[SETTINGS_KEY] ?? { theme: "system" };
}

export async function setSettings(nextSettings: {
  theme: "system" | "light" | "dark";
}) {
  await chrome.storage.local.set({ [SETTINGS_KEY]: nextSettings });
}
```

## Storage design checklist

1. Decide which values must survive browser restarts.
2. Decide which values should sync across devices, if any.
3. Version your stored data shape before the first release.
4. Keep a migration path for renamed keys or changed structures.
5. Avoid storing secrets in client-readable extension storage unless you fully accept that any extension code can read them.

## Managed storage

If you use `storage.managed`, pair your runtime code with a valid `storage.managed_schema` file in `manifest.json`. Extension.js validates and emits that schema file to the output path.

For the JSON resource details, see [JSON](/docs/implementation-guide/json).

## Common mistakes

* Using `storage.sync` for large data sets or caches.
* Assuming background in-memory variables are durable in MV3.
* Storing multiple disconnected keys without a versioning strategy.
* Mixing enterprise-managed storage with user-editable settings without separating their access patterns.

## Next steps

* Declare schema-backed enterprise storage in [manifest.json](/docs/implementation-guide/manifest-json).
* Review resource handling in [JSON](/docs/implementation-guide/json).
* Move state between contexts with [Messaging](/docs/implementation-guide/messaging).
