Skip to content

React Hooks

The @rbrowser/plugin-sdk/hooks subpath provides React bindings over the Host Bridge. All read hooks are backed by useSyncExternalStore with per-key subscriptions, so a component only re-renders when the key it reads changes.

React is a peer dependency

These hooks require React. Plugins that don't use React can ignore this entry point and use the imperative Host Bridge directly.

Provider

Wrap your tree in RBrowserHostProvider, passing the host you received in render. Hooks work anywhere inside.

import { RBrowserHostProvider, useRBrowserHost } from '@rbrowser/plugin-sdk/hooks'

createRoot(container).render(
  <RBrowserHostProvider host={host}>
    <YourUI />
  </RBrowserHostProvider>
)

Reading state

Two equivalent styles read the same reactive state.

// 1. Per-key hooks (recommended)
import {
  useSpecies,
  useSelectedRNA,
  useChannels,
  useFavorites,
  useHistory,
  useHighlightRegions
} from '@rbrowser/plugin-sdk/hooks'

const species = useSpecies()
const rna = useSelectedRNA()

// 2. Namespaced, state-path-style call sites
import { RBrowserState } from '@rbrowser/plugin-sdk/hooks'

const rna2 = RBrowserState.selectedRNA() // each member is a hook — call with ()

Each hook maps to a RBrowserState key:

Hook Returns
useSpecies() Species
useSelectedRNA() SelectedRNA \| null
useChannels() ChannelSnapshot[]
useFavorites() FavoriteEntry[]
useHistory() HistoryEntry[]
useHighlightRegions() HighlightRegionList

Storage hook

useRBrowserStorage(key, initial) is a useState-like binding over host.storage (requires storage:write):

import { useRBrowserStorage } from '@rbrowser/plugin-sdk/hooks'

const [query, setQuery] = useRBrowserStorage('lastQuery', '')

Imperative bridge

For imperative calls (navigate, highlight), reach the host with useRBrowserHost():

import { useRBrowserHost } from '@rbrowser/plugin-sdk/hooks'

const host = useRBrowserHost()
host.navigate({ chr: 'chr1', start: 100, end: 200 })
host.highlight.add({ name: 'hit', start: 100, end: 150 })