vitemple / docs
REACTIVITY / BUILT IN

A little state.
Shared everywhere.

Every generated page has one store available to its combined component scripts. Subscribe to state and update the DOM with the APIs you already know.

Component A
0
Subscribed to the same store
Component B
0
Subscribed to the same store

Try either + button. Both outputs subscribe to the same state.

01

Initialize once

The Vitemple runtime declares store before component scripts run, so it is available in every script imported through the component tree. Call store.init() in an early script slot to provide defaults before components subscribe. It fills missing fields and preserves values already restored from sessionStorage. Subscriptions run immediately with the current value.

scripts.ts
store.init({ ...store.value, counter: 0 });
02

Subscribe where you render

Each subscription receives the full state. The return value is an unsubscribe function; call it when removing a component.

Component script
const output = document.querySelector('#count');
const unsubscribe = store.subscribe((state) => {
  if (output) output.textContent = String(state.counter);
});
// Call unsubscribe() when this component is removed.
03

Update with a new object

Keep the remaining fields when changing one value. Direct nested mutation does not notify subscribers.

Button click
button.addEventListener('click', () => {
  store.update((state) => ({ ...state, counter: state.counter + 1 }));
});
04

Keep state across pages

Vitemple saves the shared store in sessionStorage and restores it when another page on the same origin loads in the same tab. The restored state is available before component scripts run. The storage key uses your project’s package.json name, such as vitemple-store:my-app , so different apps on the same origin keep separate stores while pages in one app share state.

First page · set-counter.ts
store.init({ counter: 0 });
store.set({ ...store.value, counter: 5 });
Next page · read-counter.ts
store.init({ counter: 0 });
console.log(store.value.counter); // 5
store.init() preserves restored values.

Use store.init() to provide defaults for missing fields. It leaves values restored from sessionStorage unchanged. External modules, imported via import cannot access the combined module’s lexical store, they have to be embedded via <slot> .

05

Store types are built in

Vitemple provides the global declaration for the store API. When your application extends vitemple/tsconfig.json and includes its TypeScript files, the editor recognizes store automatically. No per-file import or manual declaration is needed.

tsconfig.json
{
  "extends": "vitemple/tsconfig.json",
  "compilerOptions": {
    "noEmit": true,
    "rootDir": "src",
    "allowImportingTsExtensions": true
  },
  "include": ["src/**/*.ts"]
}
Explore the complete example ↗