ShipEasy

Install

Add the ShipEasy SDK to your application, the CLI to your machine, and (optionally) the MCP server to your AI assistant.

Production readyOn this page · 6 min readUpdated · May 3, 2026Works with · Node 20+ · Workers · Bun · Deno · Browser

ShipEasy ships as a small set of npm packages — install only the ones you need. There is one SDK, one CLI binary, and one MCP server. They all share the same login.

Pick what you need

Quick install

$npm install @shipeasy/sdk
npm install -g @shipeasy/cli
shipeasy login

That's the whole runway from zero to working. Everything below is detail.

SDK

Install the package

npm install @shipeasy/sdk
# pnpm add @shipeasy/sdk
# yarn add @shipeasy/sdk
# bun add @shipeasy/sdk

The package ships both server (Node, ShipEasy, Bun, Deno) and browser builds via conditional exports. Your bundler picks the right one automatically; you can also import the explicit subpath (/server, /client) when you want to be unambiguous (e.g. inside a monorepo with a shared util used from both).

Server initialisation

For Next.js, put this in your root layout.tsx so it runs once per cold start. For an Express or app, call it during startup. For RSC, the SDK persists state across the async-context boundary so you don't need a Provider on the server side.

import { shipeasy } from "@shipeasy/sdk/server";

await shipeasy({
  apiKey: process.env.SHIPEASY_SERVER_KEY!, // server SDK key
  env: "prod",                              // "dev" | "staging" | "prod"
});

The server SDK polls /sdk/flags and /sdk/experiments in the background. Evaluation happens locally — there is no per-request network call from your code.

Browser initialisation

import { shipeasy } from "@shipeasy/sdk/client";

shipeasy({
  apiKey: process.env.NEXT_PUBLIC_SHIPEASY_CLIENT_KEY!,
});

// Once you know who the user is:
await shipeasy.identify({ user_id: "u_4f2a", plan: "pro" });

The client SDK auto-manages an anonymous_id cookie, batches event uploads with navigator.sendBeacon on page hide, and exposes a devtools overlay at ?shipeasy=1.

One key, one configure call

Flags, experiments, and i18n share a single apiKey. There is no separate i18n.init(), no second flags.configure(). The single shipeasy() call boots all three.

Don't wrap this in a custom helper file. The SDK owns its own initialisation.

Two kinds of keys — server vs client

Server keys can read full payloads and write events. Client keys are scoped: they expose only the gates and configs you mark client-readable, and they rate-limit by domain. Never put a server key in browser code. Manage both in Project → SDK keys, or with shipeasy keys.

CLI

Install globally

$npm install -g @shipeasy/cli

Or skip the install and use it ad-hoc:

npx -y @shipeasy/cli@latest --help

Verify

bash shipeasy --version shipeasy --help

Log in

shipeasy login

Opens a browser to confirm. After confirmation, credentials are written to ~/.shipeasy/credentials (mode 0600). See Authenticate for the full flow including CI tokens.

The CLI is a thin wrapper over the same Server Actions the dashboard uses. Anything you can do in the UI, you can do from a terminal or a CI job. Full reference at CLI.

MCP server

If you use Claude Code, Cursor, Windsurf, or any other MCP-compatible AI assistant, install the ShipEasy MCP server so your agent can do setup work for you:

zsh
$

shipeasy mcp install

? Which assistants? › Claude Code, Cursor ✔ Wrote ~/.claude/settings.json ✔ Wrote .cursor/mcp.json MCP server registered. Restart your AI assistant to pick it up.

The MCP server uses your CLI credentials — no extra env vars, no separate token. See MCP server for the tool inventory and manual config.

Environment variables

The SDK reads the following from process.env (and import.meta.env in Vite). Anything passed explicitly to shipeasy({ ... }) wins.

Field
Type
Description
SHIPEASY_SERVER_KEY
string ?
Server-side SDK key. Used by the server build. Treat as a secret.
NEXT_PUBLIC_SHIPEASY_CLIENT_KEY
string ?
Client-side SDK key. Safe to expose. Vite users: VITE_SHIPEASY_CLIENT_KEY.
SHIPEASY_ENV
"dev" | "staging" | "prod" ?
Default environment when not passed explicitly. Defaults to "prod".
SHIPEASY_EDGE_URL
string ?
Override the ShipEasy base URL. Defaults to https://edge.shipeasy.dev.
SHIPEASY_API_URL
string ?
Override the admin API base URL. Defaults to https://shipeasy.ai.

Frameworks

Edge runtimes & ESM

The SDK is shipped as ESM-first with a CJS fallback for older Node. There are no Node built-ins on the hot path, so it runs unchanged on ShipEasy, Vercel Edge, Deno Deploy, and Bun.

Conditional exports cheat sheet
  • import {shipeasy} from "@shipeasy/sdk/server" — server build, picked automatically when bundling for Node/Workers. - import {shipeasy} from "@shipeasy/sdk/client" — browser build, picked when bundling for the browser. - import "@shipeasy/sdk" — re-exports both via conditional resolution. Use this only if your bundler honours exports.

Monorepo notes

In a pnpm/yarn workspace, install @shipeasy/sdk in each app that uses it (don't hoist it into the root unless your tooling resolves hoisted deps). For shared internal libraries that import from the SDK, depend on it as a peerDependency so consumers control the version.

If you depend on the SDK from a Cloudflare Worker built with CLI, no special config is needed — CLI honours exports and picks the right build.

Troubleshooting

Node 18 or older

ShipEasy requires Node 20+. Older Node versions lack stable fetch and AbortSignal.timeout. Upgrade Node, or polyfill fetch and pass it explicitly via shipeasy({ fetch: customFetch }).

Edge runtime build picks the wrong file

Some bundlers misclassify edge targets as Node. Force the right build with the explicit subpath: import {shipeasy} from "@shipeasy/sdk/server" — this works in every edge runtime we've tested.

Vite says "process is not defined"

Use import.meta.env.VITE_SHIPEASY_CLIENT_KEY rather than process.env.* in Vite, and let Vite inline it at build time. Don't pass process.env.SHIPEASY_SERVER_KEY to the client build — that key belongs only on the server.

NEXT

Log in, then ship a flag.

One command opens your browser, drops a credential file on disk, and you never think about API keys again — for interactive use. CI is one env var.

Install the CLI
$npm install -g @shipeasy/cli
Then log in
$shipeasy login
Was this page helpful?✎ Edit on GitHub

On this page