create_global_state

create_global_state is a factory function that creates a shared state hook. Unlike use_state, which creates state local to a single component, the state created by create_global_state is shared across all components that call the returned hook. When any component updates the shared state, all other components using the same hook will re-render with the new value.

Caution

Global state is shared across all users connected to the same script session or Persistent Query. When one user updates the state, every other user’s components re-render with the new value. Use create_global_state only when this is the intended behavior, such as for collaborative views or admin-controlled settings. For state that should be independent per user, use create_user_state instead.

Call create_global_state at module level (outside of any component) to create a store. Then call the returned hook inside @ui.component functions to subscribe to the shared state.

When all components using a shared store unmount, the state resets to the initial value.

Examples

Basic example

In this example, clicking the button in ui_counter_controls will update the count displayed in both ui_counter_controls and ui_counter_display.

Recommendations

  1. Create stores at module level: Call create_global_state at module level, not inside a component. The returned hook is then used inside components.
  2. Naming convention: Name the returned hook starting with use_, e.g. use_shared_counter = ui.create_global_state(0). This makes it clear that it follows hook rules.
  3. Prefer create_user_state for user-specific data: If the state should be independent per user (e.g., user preferences or user-specific selections), use create_user_state instead.

Using updater functions

Like use_state, the setter function supports updater functions for state that depends on the previous value:

When an updater function is passed, it is resolved once using the current store value and the resolved value is broadcast to all subscribers. This ensures all components see the same value regardless of timing.

Shared filter example

A common use case is sharing filter criteria across multiple views:

Custom hooks

You can wrap the hook returned by create_global_state to build a custom hook with prepackaged behavior:

Components call use_items() and get back add and clear functions instead of a raw setter. The button label in the input panel shows the count, which updates when items are cleared from the list panel.

Cleanup behavior

When all components that subscribe to a shared store unmount (e.g., all panels using the hook are closed), the store is released. This prevents memory leaks from unused state. When a new component later subscribes to the same store, it will be recreated with the initial value.

If at least one subscriber remains active, the state is preserved.

Thread safety

create_global_state is thread-safe. Multiple components can safely read and update the shared state concurrently. State updates are serialized internally using a lock.

API Reference

When all components using the store unmount, the state resets to initial_value.

Returns: Callable[[], tuple[TypeVar(T), Callable[[TypeVar(T) | Callable[[TypeVar(T)], TypeVar(T)]], None]]] A hook function that returns a (value, set_value) tuple, matching the use_state interface. The value and setter are shared across all components that call this hook.

ParametersTypeDefaultDescription
initial_valueTypeVar(T) |
Callable[[], TypeVar(T)]
NoneThe initial value for the shared state, or a callable that returns the initial value. If a callable is provided, it will be invoked once when the store is created.