Skip to main content

Overview

This page shows how to control flag values in unit tests, how the SDK behaves when you develop without network access, and how to keep local work out of production with a development environment. None of these patterns need a test-only package. They use regular TypeScript client options or Go options.

Force values in unit tests

In TypeScript, pass a bootstrap snapshot and a stub fetch that always answers 304 Not Modified; the client serves that snapshot immediately. The Go helper below serves test values as defaults and uses a stub HTTP client so no request reaches the network, which is enough for application branching tests. To test Go targeting rules, pass a snapshot as Bootstrap, as shown below.
Flags you don’t list aren’t in the snapshot, so they return their defaults.
Passing the client into the code under test (instead of importing a module-level singleton) keeps each test independent. If your code imports the singleton from src/lib/shipd.ts, mock that module with your test runner (vi.mock or jest.mock) and return a test client.

Test targeting rules

To test a targeting rule itself, add rules to a flag in the snapshot and pass context to the evaluation. In TypeScript, pass it as bootstrap; the snapshot types are in FlagSnapshot, exported from shipdit. In Go, pass the snapshot JSON as Bootstrap:
targeting_test.go
With an offline client, Ready returns the fetch error immediately instead of waiting for its deadline, or nil when Bootstrap is set.

React components

Render with a test client in ShipdProvider. Because bootstrap is set, useReady() is true after the first effect.
src/components/CheckoutNav.test.tsx

Serve only defaults

Sometimes you want a client that never contacts shipd, for example when .env has no SDK key. createClient throws if sdkKey is empty, so there’s no key-less mode. Instead, create a client with a placeholder key and a fetch that always fails. Every check returns its default.
The shipd dashboard uses this pattern so it boots from an empty .env. In a browser app, also pass persist: false so no snapshot is cached.

Develop without network access

You don’t need special configuration to work offline:
  • TypeScript ready() resolves as soon as the first fetch fails, or after readyTimeoutMs (5 seconds by default) if the request hangs. It never rejects.
  • Every check returns its default until a snapshot loads.
  • The browser client loads the last snapshot it saved in localStorage, so you keep seeing the values from your last online session.
  • Polling continues, so the client picks up the snapshot when the network returns.
Go Ready(ctx) returns a request or context error when startup fails; handle it and continue with defaults if appropriate. Go keeps snapshots in memory and does not persist them to disk. See Local evaluation for the full failure model.

Use a development environment

Keep local work away from production flags with a separate environment and SDK key.
1

Create the environment

In the dashboard, open your project’s Environments page and click Create environment. Name it Development with the slug development.
2

Create a key for it

Select the development environment, go to SDK keys, and click Create SDK key. Keys are created for the active environment.
3

Point your local env at it

.env.local
4

Push your flag definitions

A management API key is bound to one environment. Run shipd login, approve the development environment in the browser, then push:
You can now add rules, run rollouts, and change the Fallthrough in development without affecting production. See Environments.

Next