Quickstart
From zero to a flag-gated feature in production — install the SDK, create a gate, roll it out, kill-switch it, and watch it in the dashboard. Five minutes, end to end.
This walks through the full flow end to end: install the SDK, create a gate, gate code, roll it out gradually, then kill-switch it. By the end you'll have a feature behind a flag in production, evaluated locally with no per-request network call, that you can flip from your phone.
If you'd rather hand this to an AI agent, the LLM guide describes the same flow for Claude Code, Cursor, and Windsurf.
The 5-minute path
install · create · gate · roll outInstall the SDK & log in
Create a gate at 0%
Bump it to 5%, then 100%
Prerequisites
- A ShipEasy project. Sign up at shipeasy.ai — the free tier is enough for this walkthrough.
- A server SDK key scoped to your environment. Find it in Project → SDK keys → Create → server, or generate one from the CLI:
shipeasy keys create --kind server- The SDK installed in your project:
Initialise the SDK
Initialise once at boot. The server SDK polls flag updates in the background — no per-request cost, no fetch on the hot path.
import { configureShipeasy, flags } from "@shipeasy/sdk/server";
configureShipeasy({
apiKey: process.env.SHIPEASY_SERVER_KEY!,
});
export const ready = flags.init();Import this once from your entrypoint and await ready before serving the first request. After that, every flags.gate() call is synchronous and reads from in-process memory.
Flags, dynamic values, experiments, and i18n all share the same apiKey. Don't create per-feature wrappers in your codebase — the SDK owns its own initialisation.
Create a gate
From the CLI:
shipeasy flags create new-checkout-flow --rollout 0Or in the dashboard: Configs → Gates → New gate, name new-checkout-flow, leave the rollout at 0%. The default value is false — nobody sees the new path yet.
Naming conventions to save your future self pain:
- kebab-case:
new-checkout-flow, notnewCheckoutFlow. - Describe the change, not the abstract feature:
enable-redis-poolages better thanredis-pool. - Prefix by area:
checkout-,nav-,infra-. Makes deletion sweeps easy.
Gate your code
import { flags } from "@shipeasy/sdk/server";
export async function getCheckoutComponent(user) {
if (flags.gate("new-checkout-flow", user)) {
return import("./checkout/new");
}
return import("./checkout/legacy");
}gate() is synchronous and reads from the in-process cache. Pass any user attributes you want available to targeting rules — at minimum { user_id }. The shape of user is just a plain object:
{
user_id: "u_4f2a", // required for deterministic bucketing
plan: "pro", // any attribute your rules want
country: "US",
tenure_days: 142,
}Test locally with overrides
Add yourself to the overrides list in the dashboard (Gate → Overrides → Always on, paste your user_id). The flag returns true for you and false for everyone else — no rollout math involved.
If you have the browser DevTools overlay loaded, you can also force a value with a query param:
https://app.local/?shipeasy_gate_new-checkout-flow=trueThat's persisted in localStorage and survives reloads until you toggle it off.
Roll it out gradually
Bump the rollout from 0% → 5% → 25% → 100% over a few hours, watching your error rate and p95.
shipeasy flags rollout new-checkout-flow --percent 5
shipeasy flags rollout new-checkout-flow --percent 25
shipeasy flags rollout new-checkout-flow --percent 100Bucketing is deterministic by user_id, so the same 5% always sees the new path. You won't see flicker as you bump the percentage — you only ever add users to the bucket, never reshuffle.
A safe schedule for an unknown-risk change:
0% → enable rule + dogfood with overrides
1% → 1 hour, watch error rate + p95
5% → 4 hours
25% → overnight
50% → 1 day
100% → keep an eye on it for a week, then delete the flagKillswitch (when something breaks)
If something goes wrong, flip the killswitch. It overrides every targeting rule and serves false everywhere within the SDK's next poll (default 30s, faster on Pro).
shipeasy flags disable new-checkout-flow --killswitchDashboard: toggle the red Killswitch chip on the gate row. The killswitch is a separate field from enabled, so flipping it preserves your targeting rules and rollout — re-enabling restores the full prior state.
Wire it into CI
Add a check that fails the build if you reference a flag that doesn't exist on the project:
- name: Validate flags
run: shipeasy flags validate ./srcThis catches typos (new-checkut-flow) and stale references after a flag has been deleted.
What just happened
When you flipped that rollout from 25 to 100, ShipEasy propagated the change worldwide. Within
the SDK's poll interval (default 30s, 10s on Pro, push on Enterprise), every server saw the new
value.
No deploy. No restart. No backend round-trip on the read.
An audit log of every change, side-by-side dashboards for the affected gate, deterministic bucketing per user, and a kill-switch you can hit from your phone. You didn't have to build any of it.
Where to next
Add precision→
Replace "5% of everyone" with "100% of plan=pro in country=US".
Tune values without code→
pricing.base = 9.99 can be a config, not a constant.
Add a killswitch→
Wrap critical paths so you can disable them instantly during an incident.
Measure, don't guess→
Once it's gated, run an experiment on the same flag.
Hand it to an AI agent.
The same flow, but driven by Claude Code or Cursor through the MCP server. You answer one auth prompt, the agent creates the gate, wires the SDK, and opens the PR.