Solid
@flagward/solid — provider, useFlag, and useFlags.
Installation
npm install @flagward/solidRequires Solid 1.8 or newer. @flagward/core comes with it — you do not
install it separately.
Quick start
Wrap the app in the provider once:
// index.tsx
import { render } from 'solid-js/web';
import { FlagwardProvider } from '@flagward/solid';
import App from './App';
render(
() => (
<FlagwardProvider apiKey="your-environment-api-key" host="https://flags.example.com">
<App />
</FlagwardProvider>
),
document.getElementById('root')!,
);Then ask for a flag wherever the decision is actually made:
import { useFlag } from '@flagward/solid';
function Checkout() {
const { value, isLoading } = useFlag('new-checkout');
return (
<Switch>
<Match when={isLoading()}>
<LegacyCheckout />
</Match>
<Match when={value()}>
<NewCheckout />
</Match>
<Match when={!value()}>
<LegacyCheckout />
</Match>
</Switch>
);
}The value is an accessor
Hooks return Accessors, so calling them inside JSX keeps the fine-grained
tracking Solid is built around:
const { value } = useFlag('new-checkout');
return (
<Show when={value()} fallback={<LegacyCheckout />}>
<NewCheckout />
</Show>
);A plain if (value()) in the component body runs once, outside any tracking
scope, so it does not re-run when the flag changes. Read the accessor inside
JSX, createMemo, or createEffect when the result must stay live.
The context can be reactive
Everywhere a context is taken — the provider, useFlag, getFlag — it
accepts a signal or a plain getter as readily as a plain object:
const [user, setUser] = createSignal({ plan: 'standard' });
const { value } = useFlag('beta', user);
setUser({ plan: 'pro' }); // the flag re-evaluates, the DOM updatesHooks
Reach for useFlag. useFlags earns its place when the keys are not known
where you write the code, when you need a flag where a hook cannot go
(getFlag runs anywhere), or when a component reads several flags:
const { flags, isLoading, error, getFlag } = useFlags();
flags(); // { "new-checkout": true, ... }
getFlag('beta'); // one flag, app context
getFlag('beta', { plan: 'pro' }); // one flag, this contextWhere context comes from
<FlagwardProvider apiKey={apiKey} context={user}> // who the user is
useFlag('beta', { plan: 'pro' }) // just this callA context passed to useFlag belongs to that call only — it is not
published anywhere, and the map useFlags returns resolves against the
provider's context alone.
Losing the network
The provider opens an SSE stream and keeps it in step on its own: a flag
changed on the server reaches every component within a second, coming back
online re-reads the flags, and where there is no EventSource — server
rendering, plain Node — live updates are reported as off while the flags
already read keep working.
Outside Solid
import { FlagwardClient, evaluateFlag } from '@flagward/solid';The client and the evaluator are re-exported here, so a store, a route guard, or a plain module can use them without a component.