Skip to main content

Overview

Coding assistants know little about shipd. Give them this page and they’ll write correct shipd code. It’s also available as plain Markdown at https://docs.useshipd.com/ai.md. The navbar separates Docs, Guides, SDKs, Integrations, API docs, Tutorials, and Changelog. Shared examples have synchronized TypeScript and Go tabs: choose an SDK once to switch the matching examples on that page. Framework-specific examples document the SDK supported by that framework. For direct application control, connect an agent through MCP under Guides → Operations. The endpoint is https://mcp.useshipd.com/mcp; mutations require idempotency keys and updates require observed versions. Pending changes must be reviewed in the dashboard. MCP tools and request guarantees live under API docs → Operations APIs. Every page also has a menu to copy it as Markdown or open it in Claude, ChatGPT, or Cursor. To give your assistant shipd context permanently, add this to your project’s CLAUDE.md, AGENTS.md, or editor rules:

shipd context for coding assistants

shipd is a feature flag service. Flags are defined in TypeScript, Go, or version-1 JSON, synced with a shared CLI, and evaluated locally in memory by an SDK.

Packages

Go workflow

The CLI reads shipd.config.go directly and generates Go accessors by default, unless typesLanguage overrides the output language. Define an exported var Config = config.ShipdConfig{...} in a self-contained Go file inside your module. The CLI evaluates that file with Go; imported packages and helper declarations in the same file are supported. It does not load sibling Go files, so keep application dependencies in imported packages. Do not define main in the definition file. shipd pull rewrites the Go definitions and regenerates accessors; review the resulting diff because comments and helper code are replaced. Use generated accessors like flags.NewCheckout(client, ctx) and flags.Defaults().

Files

Define flags

Then run shipd push. It creates missing flags, updates changed definitions, and regenerates TypeScript types or Go accessors. It never deletes flags; --prune archives flags missing from the file.

Evaluate on a server

Streaming requires a WebSocket implementation. Node.js 22+ provides one globally. On Node.js 20, supply a compatible constructor through the WebSocket option; otherwise, the client uses polling.

Evaluate in React

src/lib/shipd-react.ts

Evaluation model

  • The SDK downloads a snapshot of one environment from https://edge.useshipd.com, keeps it in memory, and refreshes it every 30 seconds or on a WebSocket notification.
  • isEnabled, getVariant, getNumber, and getJson make no network requests and never throw.
  • Value order: no snapshot or unknown key → defaults[key]; flag disabled → fallthrough, skipping rules; first matching rule → its serve; otherwise → fallthrough.
  • Evaluation context is { userId?, attributes?, segmentIds? }. Per-call context overrides createClient({ context }). In browsers (shipdit/client), identify() traits sit between the two; server identify() only records an event and never changes context.
  • Percentage rollouts hash the flag key and userId, or a chosen attribute. A missing bucket attribute makes the condition fall through.
  • Targeting rules, rollouts, and enabled state are set in the dashboard, not in shipd.config.ts or shipd.config.go.

Credentials

Rules for assistants

  1. Import defineFlags from shipdit/config, never from shipdit.
  2. Import createClient from shipdit on servers and from shipdit/client in browsers.
  3. Type the client with the generated FlagDefinitions: createClient<FlagDefinitions>(…). Never write flag types by hand.
  4. Pass a defaults entry for every flag. Use the safe value (usually “off”).
  5. Create one client per process and reuse it. Never create a client per request.
  6. await shipd.ready() once at startup, before serving traffic that reads flags.
  7. On servers, pass { userId, attributes } per call. Server identify() only records an event; it never sets evaluation context.
  8. Call createShipdReact once, in a "use client" module, and use hooks from that same call.
  9. Add or change flags by editing shipd.config.ts (Go: shipd.config.go) and running shipd push. Don’t create flags in the dashboard for code-managed projects.
  10. Don’t pass endpoint or streamEndpoint; they were removed. Use stream: true for realtime updates. For a custom stream gateway, preserve its URL with overrides.streamEndpoint and stream: true. Reserve overrides.unsafeEndpoint for development and tests; never use it in production.

Rules for Go

  1. Import the SDK as shipd "github.com/alasti-company/useshipd.com/sdks/go" and definitions from its config subpackage. One go get github.com/alasti-company/useshipd.com/sdks/go installs both.
  2. Define flags in shipd.config.go, never shipd.config.ts. Run shipd types gen (Node.js 22.12+ and @shipdit/cli) to write accessors.
  3. Call generated accessors such as flags.NewCheckout(client, ctx) instead of client.IsEnabled("new-checkout", ctx), and pass Defaults: flags.Defaults() to shipd.New.
  4. Create one *shipd.Client per process with shipd.New and share it across goroutines.
  5. Call Ready once at startup with a bounded context. It returns the fetch error as soon as the first fetch fails; log it and serve defaults.
  6. Pass a shipd.EvaluationContext on every evaluation. Identify only queues telemetry.
  7. On shutdown, call Shutdown(ctx) with a bounded context. It attempts to flush pending events and closes even on delivery failure; check or log its returned error. Close does not flush. Never set Overrides.UnsafeEndpoint in application code.
  8. JSON flags return any and numbers are float64; convert at the call site.
  9. In tests, use an HTTPClient that fails, DisablePolling, and DisableEvents. To test targeting rules, pass snapshot JSON as Bootstrap.

Common mistakes

Don’t:
  • Call the edge API directly to evaluate flags.
  • Put a server SDK key, management API key, or service account token in browser code.
  • Use a management API key or service account token as an SDK key, or an SDK key with the CLI.
  • Edit src/generated/flags.ts by hand.
  • Assume shipd push deletes flags missing from shipd.config.ts. It leaves them; --prune archives them.
  • Run shipd push --prune without reading the plan. It archives every flag not in the file.
  • Put targeting rules or rollout percentages in shipd.config.ts. They’re dashboard state.
  • Forget that default in shipd.config.ts is the fallthrough of the environment you push to. shipd push resets a fallthrough changed in the dashboard back to it. Update default (or run shipd pull) first.
  • Assume disabling a flag turns it off. A disabled flag serves its fallthrough. To turn a feature off, set the fallthrough to false.
  • Use --force to get past a conflict. Run shipd pull, re-apply the edit, and push again.
  • Treat shipd push exit code 5 as success. The change is waiting for approval.
  • Rely on percentage rollouts without supplying their bucket attribute (userId by default).
  • Import shipdit/client/react in server code.
Do:
  • Supply defaults for every flag.
  • Evaluate locally with the SDK.
  • Commit src/generated/flags.ts along with shipd.config.ts (Go: flags_gen.go along with shipd.config.go).
  • Run shipd diff --exit-code in pull request CI, and shipd push --ci on merge with a service account token in SHIPD_API_KEY.
  • Set SHIPD_API_URL=https://api.useshipd.com in CI. Without a saved login, the CLI defaults to http://localhost:8000.
  • Await shipd.close() on shutdown. In Go, drain active handlers first, then call Shutdown(ctx) with a bounded context and check its error.

CLI cheat sheet

Where to look next