Storage

Typed wrappers around chrome.storage.local. Use these instead of raw chrome.storage calls — they handle serialization, defaults, and subscriptions.

Read and write

import {
  getStorageValue,
  setStorageValue,
  removeStorageValue,
} from "@/shared/storage";

await setStorageValue("draft", { title: "Hello" });
const draft = await getStorageValue<{ title: string }>("draft");
await removeStorageValue("draft");

Update with a callback

The callback receives the current value (or null) and returns the new value. Handles read-then-write so you don't have to manage the two-step pattern yourself.

import { updateStorageValue } from "@/shared/storage";

await updateStorageValue<number>("credits", (current) => (current ?? 0) + 1);

Subscribe to changes

Returns an unsubscribe function. Fires when any surface changes the key. Use this to keep UI in sync across popup, side panel, and options.

import { subscribeToStorageKey } from "@/shared/storage";

const unsubscribe = subscribeToStorageKey("credits", (value) => {
  console.log("credits changed:", value);
});

// Later: unsubscribe();

When to use storage vs messaging

Prefer storage for durable cross-surface data: settings, drafts, cached API responses, user preferences. Prefer messaging for commands, one-shot requests, and background orchestration.