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:
- The resolved environment is
'development' - A
devKeyis present (set via theSKYSTATE_DEV_KEYenvironment variable) - A config key is read with a fallback value (e.g.
useProjectConfig('banner.enabled', true)) - The key does not exist in the current config
- 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:
skystate initskystate 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
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.
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_KEYis only set in.env.localor.env.development, not in.env.production. Vite will not expose variables from.env.localin production builds. - The dev key grants write access to the
developmentenvironment only. It cannot modifystagingorproductionconfig. - Add
.env.localto your.gitignoreto avoid committing the dev key to version control.