Skip to content

Auto-registration

Auto-registration is a development-mode feature that creates missing config keys in SkyState the first time they are read with a fallback value. This means you can write code that references config keys, run your app locally, and the keys appear in SkyState automatically — no separate setup step required.


How It Works

When all of the following conditions are true, the SDK will create a missing key:

  1. The resolved environment is 'development'
  2. A devKey is present (set via the SKYSTATE_DEV_KEY environment variable)
  3. A config key is read with a fallback value (e.g. useProjectConfig('banner.enabled', true))
  4. The key does not exist in the current config
  5. The initial load has completed (isLoading is false)

When these conditions are met, the key and its fallback value are enqueued for registration. After a 50 ms debounce window, all enqueued keys are sent to the server as a single PATCH request. This batching means a component that reads ten missing keys on first render sends one request, not ten.

Console output

During auto-registration, the SDK logs each key being created:

[SkyState] Key 'banner.enabled' not found. Auto-creating with default: true
[SkyState] Key 'banner.text' not found. Auto-creating with default: "Hello!"

Conflict handling

If two concurrent instances try to create the same key simultaneously (for example, in two browser tabs), one will receive a 409 Conflict response. The SDK handles this gracefully: on a 409, it re-fetches the config to get the latest state instead of retrying the registration. This ensures both tabs converge on the same config without errors.

Each key is attempted once

Auto-registration is idempotent per store instance. Once a key has been enqueued, it will not be enqueued again even if the component re-renders. This prevents duplicate PATCH requests.


Setup

Step 1: Obtain a dev API key

The dev key is a project-scoped API key that grants write access to the development environment. Obtain it from the SkyState dashboard or with the CLI:

bash
skystate init

skystate init writes the dev key to a .env file in your project root:

SKYSTATE_DEV_KEY=devkey_abc123...

Step 2: Set the environment variable

The SDK reads the dev key from the environment variable SKYSTATE_DEV_KEY. You do not pass it as a prop.

For Vite projects, add the variable to your .env file (or .env.local):

SKYSTATE_DEV_KEY=devkey_abc123...

The SkyStateProvider reads the key from import.meta.env.SKYSTATE_DEV_KEY (Vite) or process.env.SKYSTATE_DEV_KEY (Node.js/webpack). When the key is found and the resolved environment is development, auto-registration is enabled automatically.

Step 3: Use fallback values in your code

tsx
import { useProjectConfig } from '@skystate/react';

export function Banner() {
  const { data: enabled } = useProjectConfig<boolean>('banner.enabled', true);
  const { data: text } = useProjectConfig<string>('banner.text', 'Hello!');

  if (!enabled) return null;
  return <div>{text}</div>;
}

On first render in development, if banner.enabled and banner.text do not exist in SkyState, the SDK creates them with the values true and "Hello!" respectively. After the PATCH succeeds, the SDK re-fetches the config and updates the cache.


Production Behaviour

In production (no devKey), the SDK never writes to SkyState. If a key is read with a fallback and the key does not exist, the SDK logs a warning and returns the fallback value:

[SkyState] Key 'banner.enabled' not found in config. Using default value.

This warning indicates a key is referenced in your code but not present in your production config. You should push the key to production before deploying code that references it.


The AutoRegistrar Class

Auto-registration is implemented by the AutoRegistrar class, which is exported from @skystate/core for advanced use cases. Normally you do not interact with it directly.

typescript
export class AutoRegistrar {
  constructor(
    debounceMs: number,
    onFlush: (entries: Map<string, unknown>) => Promise<void>,
  );

  enqueue(key: string, defaultValue: unknown): void;
  dispose(): void;
}

AutoRegistrar is created by ConfigStore when devKey is present and the environment is development. ConfigStore.registerIfMissing() calls AutoRegistrar.enqueue(), which debounces and batches registrations before calling onFlush with the pending entries.


Security Notes

  • The dev key is only used in development mode. It is read from a build-time environment variable and never bundled into production builds if your tooling is configured correctly.
  • For Vite, ensure that SKYSTATE_DEV_KEY is only set in .env.local or .env.development, not in .env.production. Vite will not expose variables from .env.local in production builds.
  • The dev key grants write access to the development environment only. It cannot modify staging or production config.
  • Add .env.local to your .gitignore to avoid committing the dev key to version control.

Built with VitePress