Skip to content

@skystate/react

@skystate/react provides a React context provider and hooks that integrate SkyState remote config into React applications. It is built on @skystate/core and uses useSyncExternalStore for efficient, concurrent-safe rendering.


Installation

bash
npm install @skystate/react

@skystate/react depends on @skystate/core. You do not need to install @skystate/core separately.

React 18 or later is required.


Public API

Provider

ExportDescription
SkyStateProviderContext provider. Wrap your app (or a subtree) to make config available to hooks.
SkyStateProviderPropsTypeScript type for the provider's props.

Hooks

ExportDescription
useProjectConfig(path, fallback?)Read a config value and subscribe to changes.
useProjectConfigStatus()Read the connection status: lastFetched and error.

Utilities

ExportDescription
defaultReactResolverThe default environment resolver used by SkyStateProvider. Reads import.meta.env.MODE or process.env.NODE_ENV.

Re-exported from @skystate/core

ExportDescription
SkyStateErrorTyped error class with code and optional status.
ConfigEnvelopeType: { version, lastModified, config }
VersionType: { major, minor, patch }
EnvironmentType: 'development' | 'staging' | 'production'

Sections


Quick Example

tsx
// main.tsx — wrap your app in the provider
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { SkyStateProvider } from '@skystate/react';
import App from './App';

const apiUrl = import.meta.env.VITE_SKYSTATE_API_URL ?? 'https://api.skystate.io';
const accountSlug = import.meta.env.VITE_SKYSTATE_ACCOUNT_SLUG ?? 'my-account';
const projectSlug = import.meta.env.VITE_SKYSTATE_PROJECT_SLUG ?? 'my-project';

createRoot(document.getElementById('root')!).render(
  <StrictMode>
    <SkyStateProvider
      apiUrl={apiUrl}
      accountSlug={accountSlug}
      projectSlug={projectSlug}
      resolveEnvironment={() => import.meta.env.MODE ?? 'development'}
    >
      <App />
    </SkyStateProvider>
  </StrictMode>,
);
tsx
// FeatureFlag.tsx — read a config value in a component
import { useProjectConfig } from '@skystate/react';

export function NewCheckoutButton() {
  const { data: enabled, isLoading } = useProjectConfig<boolean>(
    'features.newCheckout',
    false,
  );

  if (isLoading) return null;
  if (!enabled) return <LegacyCheckoutButton />;
  return <NewCheckoutButton />;
}
tsx
// StatusBar.tsx — display connection status
import { useProjectConfigStatus } from '@skystate/react';

export function StatusBar() {
  const { lastFetched, error } = useProjectConfigStatus();

  if (error) return <div>Config error: {error.message}</div>;
  if (!lastFetched) return <div>Connecting...</div>;
  return <div>Config synced at {lastFetched.toLocaleTimeString()}</div>;
}

How Rendering Works

@skystate/react uses React's useSyncExternalStore to subscribe to the ConfigStore. This means:

  • Components re-render only when the specific config path they subscribed to changes.
  • A component reading 'banner.text' does not re-render when 'features.maxItems' changes.
  • Object references are stable across renders when values have not changed (structural sharing in the cache).
  • The provider and hooks are safe to use in React Strict Mode and React Concurrent Mode.

Built with VitePress