
Onboardingv2
- 122 installs
- Updated July 30, 2026
- launchdarkly/experimental-agent-skills
Implement LaunchDarkly-guided onboarding flows, feature-flag rollouts, and progressive agent enablement in SaaS products without hand-writing flag wiring each time.
About
onboardingv2 from launchdarkly/experimental-agent-skills teaches agents to wire LaunchDarkly-style onboarding, feature flags, and progressive enablement into SaaS apps. It standardizes experiment setup, rollout guards, and agent-safe defaults so new users and capabilities ship incrementally without bespoke flag plumbing each sprint.
- LaunchDarkly onboarding patterns
- Feature-flag driven rollout
- Progressive agent enablement
- SaaS experiment wiring
- Guarded production releases
Onboardingv2 by the numbers
- 122 all-time installs (skills.sh)
- Ranked #3,788 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/launchdarkly/experimental-agent-skills --skill onboardingv2Add your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 122 |
|---|---|
| Last updated | July 30, 2026 |
| Repository | launchdarkly/experimental-agent-skills ↗ |
What it does
Implement LaunchDarkly-guided onboarding flows, feature-flag rollouts, and progressive agent enablement in SaaS products without hand-writing flag wiring each time.
Files
LaunchDarkly MCP Server Configuration (onboarding)
Configures the LaunchDarkly hosted MCP server so flag management skills and onboarding can use MCP tools. Uses OAuth for authentication — no API keys needed for the hosted server.
This skill is nested under LaunchDarkly onboarding; the parent skill's Step 4 hands off here.
Prerequisites
- A LaunchDarkly account (when directing users to sign up, use the resolved signup URL from the parent skill's Source Attribution; default:
https://app.launchdarkly.com/signup?source=agent) - An MCP-compatible coding agent
Hosted MCP Servers
LaunchDarkly provides a unified hosted MCP server for all functionality:
| Server | URL | Purpose |
|---|---|---|
| LaunchDarkly (unified) | https://mcp.launchdarkly.com/mcp/launchdarkly | Feature flags and AgentControl |
The legacy mcp/fm and mcp/aiconfigs URLs are deprecated — migrate any existing usage to the unified server (see Edge Cases).
For onboarding, the unified server is all that's needed.
Workflow
Step 1: Detect the Agent
If the parent onboarding skill already identified the agent, use that context. Otherwise infer from agent-specific directories, config files, and the tools available to you at runtime. Do not ask the user — pick the strongest match.
Step 2: Try Quick Install
The fastest path is the quick install link. Present it to the user:
LaunchDarkly MCP: https://mcp.launchdarkly.com/mcp/launchdarkly/install
Important: tell the user what to expect after clicking the link. The install link may open in the browser, but the authorization or "add server" prompt typically appears back in the coding environment (the editor or host app where the agent runs), not in the browser. Immediately after presenting the link, include guidance like:
- After clicking the link, watch your coding environment (the editor where this conversation is running) for an approval dialog, an "add MCP server" prompt, or a tools/integrations panel notification.
- The browser may start the OAuth flow, but you'll likely need to confirm or approve the server in the editor itself.
- If no prompt appears: check the editor's MCP, integrations, or tools settings area to see if the server was added but needs to be enabled. If it's not there at all, fall back to manual setup (Step 3 below).
If the quick install link doesn't work (agent doesn't support it, or user prefers manual setup), proceed to Step 3.
Step 3: Manual Configuration
Locate the MCP config file for the detected agent and add the hosted server entry. See MCP Config Templates for the exact JSON per agent.
| Agent | Config file location |
|---|---|
| Cursor | .cursor/mcp.json (project) or global Cursor settings |
| Claude Code | .mcp.json (project) or ~/.claude.json (global) |
| GitHub Copilot | Repo Settings on GitHub.com → Copilot → Cloud agent → MCP (see MCP UI links) |
| Windsurf | Agent-specific MCP config |
Add the unified LaunchDarkly server for onboarding. This single server handles feature flags and AgentControl.
Step 4: Agent-Specific Authorization
After writing the config, some agents need extra steps. Do not send users through long manual menu paths only—use MCP UI links (HTTPS docs + command: shortcuts for VS Code / Cursor).
Cursor:
1. Open MCP in Cursor using the Cursor MCP doc link and in-app shortcuts (e.g. Settings search via command: link when clickable). 2. Toggle on LaunchDarkly feature management (or the name from your config). 3. Click Connect to authorize with the LaunchDarkly account.
VS Code (when applicable):
- Use VS Code MCP doc + `mcp.json` / Settings links; trust or start the server if prompted.
Claude Code:
- Authorization happens automatically on first MCP tool call via OAuth prompt. File-based setup: Claude Code MCP doc.
GitHub Copilot:
- Click Save after adding the MCP configuration in repo settings. Use the GitHub Copilot MCP doc for the exact Settings path on github.com.
Step 5: Verify MCP Tools (No Mandatory Restart)
Restart is no longer required for Cursor or Claude Code after enabling an MCP server. Probe for tools immediately after the user confirms they've enabled and authorized the server.
1. Tell the user to enable and authorize the server. In Cursor: toggle on the LaunchDarkly server in MCP settings and click Connect. In Claude Code: the OAuth prompt appears on first tool call. Do not tell them to restart yet.
2. Probe immediately. After the user confirms the server is enabled, call a lightweight MCP tool (e.g. list-feature-flags with the user's project key). Do not ask the user whether MCP is working — just try it.
- Success (normal response, even an empty flag list): MCP is live. Note it in the onboarding log and continue.
- Auth error (401, 403, "unauthorized", "forbidden", or OAuth-related message): the server was found but authorization failed. Go to step 3a.
- Tool not found or timeout (tool not recognized, connection refused, no response): the editor hasn't picked up the server yet. Go to step 3b.
3a. Auth failure path. The MCP server is reachable but OAuth is incomplete or expired — restarting the editor won't help.
- Tell the user: "The MCP server responded but authorization failed. In Cursor: open MCP settings, find the LaunchDarkly server, and click Connect to re-authorize. In Claude Code: the next MCP tool call should re-trigger the OAuth prompt."
- Use MCP UI links to give the user a direct shortcut to their agent's MCP settings.
- Re-probe after the user confirms they re-authorized.
- If the re-probe succeeds: continue with onboarding.
- If it fails again: update the onboarding log with "MCP auth failed after re-authorization attempt" and offer the retry one-liner (see step 4 below). Do not suggest a restart for a persistent auth problem.
3b. Server-not-found path. The editor likely hasn't loaded the new MCP config yet.
- Update the onboarding log (
LAUNCHDARKLY_ONBOARDING.md) with the current state and set Next step to "Verify MCP after restart". - Tell the user: "The MCP tools aren't visible yet. Some editors need a restart to pick up new MCP servers. Restart your editor and say 'continue LaunchDarkly onboarding' when you're back — I'll resume from here."
- Be specific about how to restart: "Restart Cursor" / "reload Claude Code" / "refresh the Copilot agent" depending on what you detected in Step 1.
4. On resume after restart: The parent onboarding skill handles resume via the log file. When the next turn starts:
- Re-probe for MCP tools silently.
- If tools are now available: "MCP is connected." Continue with onboarding.
- If tools still missing: note the failure in the onboarding log. Do not block the rest of onboarding — remaining steps must still be completable without MCP. Offer a one-liner to retry later: "You can set up MCP anytime by clicking [quick install link] and restarting."
5. If the failure looks like a config issue (wrong file path, server not enabled), mention the likely cause so the user can fix it on their own time — but do not block progress.
Edge Cases
- User already has MCP configured: Verify by checking for existing LD MCP entries in the config. If the unified server (
mcp/launchdarkly) is present and working, skip configuration. If the deprecatedmcp/fmormcp/aiconfigsis present, see below. - User has the deprecated `mcp/aiconfigs` or `mcp/fm` server: These URLs are deprecated. Do not auto-migrate. Use a blocking question:
{
"questions": [
{
"id": "legacy_migration",
"prompt": "I found a deprecated LaunchDarkly MCP URL in your config (mcp/fm or mcp/aiconfigs). It should be replaced with the unified LaunchDarkly server (mcp/launchdarkly), which handles both feature flags and AgentControl. Do you want me to migrate?",
"options": [
{ "id": "yes", "label": "Yes, remove the old server and add the unified one" },
{ "id": "no", "label": "No, leave it as is for now" }
]
}
]
}- If yes: remove the deprecated entry, ensure the unified
mcp/launchdarklyserver is present (do not duplicate if it's already there), and continue. - If no: note in the onboarding log that migration was declined. Continue with onboarding — the deprecated server may still work for now.
- User has the legacy `mcp/fm` server: No migration needed —
mcp/fmmirrors the unified server and continues to work. Do not suggest removing it. - User has the old npx-based local server: Migrate them to the hosted server. Remove the old
npx @launchdarkly/mcp-serverentry and anyLD_ACCESS_TOKENenv vars. Replace with the hosted server config. - Agent not in known list: Provide the generic pattern: the user needs to add an MCP server entry pointing to
https://mcp.launchdarkly.com/mcp/launchdarklyusing whatever format their agent expects. - User opts out of MCP during onboarding: Document that choice and continue; do not block SDK work.
What NOT to Do
- Don't configure a local npx-based server. Always use the hosted server.
- Don't ask for or store API keys. The hosted server uses OAuth.
- Don't auto-migrate from the deprecated
mcp/aiconfigs— always ask via the blocking question. - Don't suggest restart as the first step — probe for tools immediately after the user enables the server.
- Don't suggest restart for auth errors (401/403) — the server was found, so a restart won't help. Guide the user to re-authorize instead.
References
- MCP UI links — HTTPS +
command:links to open MCP settings (Cursor, VS Code, Claude Code, Windsurf, GitHub) - MCP Config Templates — hosted OAuth JSON per agent; migration from deprecated configs
- Official MCP docs — full hosted setup guide
MCP Config Templates
Per-agent JSON snippets for configuring the LaunchDarkly hosted MCP server. All configurations use OAuth — no API keys required.
Source: https://launchdarkly.com/docs/home/getting-started/mcp-hosted
Unified Server (Recommended)
Use the unified server URL for new configurations:
| Server | URL | Purpose |
|---|---|---|
| LaunchDarkly (unified) | https://mcp.launchdarkly.com/mcp/launchdarkly | Feature flags and AgentControl |
Legacy URLs (deprecated):
mcp/fm— deprecated. Migrate to the unified server.mcp/aiconfigs— deprecated. Migrate to the unified server.
See mcp-configure Edge Cases for migration guidance.
Cursor
Config file: .cursor/mcp.json in the project root.
Unified server (recommended)
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly",
"headers": {}
}
}
}Legacy feature management only (deprecated)
Deprecated: mcp/fm is deprecated. Use the unified server URL above.{
"mcpServers": {
"LaunchDarkly feature management": {
"url": "https://mcp.launchdarkly.com/mcp/fm",
"headers": {}
}
}
}After adding the config: enable the server and complete OAuth in Cursor's MCP UI. Use MCP UI links — Cursor (HTTPS doc + optional command: links); do not rely only on nested Settings menu paths.
Claude Code
Config file: .mcp.json in the project root, or ~/.claude.json for global config.
Unified server (recommended)
{
"mcpServers": {
"LaunchDarkly": {
"type": "http",
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly"
}
}
}Legacy feature management only (deprecated)
Deprecated: mcp/fm is deprecated. Use the unified server URL above.{
"mcpServers": {
"LaunchDarkly feature management": {
"type": "http",
"url": "https://mcp.launchdarkly.com/mcp/fm"
}
}
}Authorization happens automatically via OAuth prompt on first MCP tool call.
GitHub Copilot
Configured via the GitHub web UI, not a local config file.
1. Navigate to the target repository on GitHub 2. Go to Settings > Code and automation > Copilot > Coding agent 3. In the MCP configuration section, add:
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly",
"headers": {}
}
}
}4. Click Save
Windsurf
Windsurf uses a similar MCP configuration format. Add to the agent's MCP config:
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly"
}
}
}Consult Windsurf's documentation for the exact config file location.
Migrating from Deprecated mcp/fm
The mcp/fm URL is deprecated. Replace it with the unified server.
Remove this:
{
"mcpServers": {
"LaunchDarkly feature management": {
"url": "https://mcp.launchdarkly.com/mcp/fm",
"headers": {}
}
}
}Replace with:
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly",
"headers": {}
}
}
}Migrating from Deprecated mcp/aiconfigs
The mcp/aiconfigs URL is deprecated. Replace it with the unified server.
Remove this:
{
"mcpServers": {
"LaunchDarkly AI Configs": {
"url": "https://mcp.launchdarkly.com/mcp/aiconfigs",
"headers": {}
}
}
}Replace with:
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly",
"headers": {}
}
}
}The unified server handles both feature flags and AgentControl. If you also had mcp/fm, migrate it to the unified server — mcp/fm is deprecated and will be removed.
Note: Do not auto-migrate. Always ask the user via a blocking question before making changes (see mcp-configure Edge Cases).
Migrating from the Old Local Server
If the user has the old npx-based server configured with an inline API key, replace it with the hosted unified server:
Remove this:
{
"mcpServers": {
"LaunchDarkly": {
"command": "npx",
"args": [
"-y", "--package", "@launchdarkly/mcp-server",
"--", "mcp", "start",
"--api-key", "api-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
]
}
}
}Replace with the unified hosted server:
{
"mcpServers": {
"LaunchDarkly": {
"url": "https://mcp.launchdarkly.com/mcp/launchdarkly",
"headers": {}
}
}
}Also remove any LD_ACCESS_TOKEN or LAUNCHDARKLY_API_KEY environment variables that were used for the local server. The hosted server handles authentication via OAuth.
Open MCP settings (links instead of menu paths)
Use this reference when onboarding tells the user to enable MCP, connect OAuth, or open MCP configuration. Give clickable links—do not rely only on "Settings → … → Tools & MCP" prose.
How to use (agents)
1. Use the row for the detected client (see parent onboarding Step 2: Detect the Agent). 2. Always include the HTTPS documentation link for that client—it opens in the browser and works from any environment. 3. When the user is in VS Code or Cursor, also include the `command:` links on their own lines so they can click in the editor chat (same scheme VS Code uses for trusted markdown). If a command: link is not clickable or does nothing, fall back to the doc link or Command Palette text below. 4. Path caveat: LaunchDarkly's Cursor template uses project .cursor/mcp.json. VS Code's MCP: Open User/Workspace Configuration commands open VS Code's mcp.json locations (often under .vscode/ or the user profile)—not .cursor/mcp.json. If the user edited .cursor/mcp.json, point them at the Cursor doc link or "open .cursor/mcp.json in the editor" plus Cursor's MCP panel.
Clients
| Client | Documentation (open in browser) | In-app shortcuts (VS Code–compatible hosts) |
|---|---|---|
| Cursor | Model Context Protocol (MCP) — Cursor Docs | Open Settings (filtered search: `mcp`) |
| VS Code (GitHub Copilot Chat, built-in MCP, etc.) | Add and manage MCP servers in VS Code | Open user `mcp.json` · Open workspace folder `mcp.json` · Open Settings (filtered search: `mcp`) |
| Claude Code | Connect Claude Code to tools through MCP | Config is file-based (project .mcp.json or user config)—open those files in the editor; no shared command: URI across versions. |
| Windsurf | MCP — Windsurf Docs | Use Windsurf's documented MCP / Cascade UI. |
| GitHub Copilot (cloud agent, repo settings) | Extend Copilot coding agent with MCP — GitHub Docs | Configuration is on github.com under the repository's Settings (see doc). Optional: MCP and Copilot coding agent (concepts). |
Command Palette text (fallback)
If links are not clickable:
- VS Code / Cursor: Run MCP: Open User Configuration, MCP: Open Workspace Folder Configuration, or MCP: List Servers from the Command Palette (
⇧⌘P/Ctrl+Shift+P). Alternatively Preferences: Open Settings (UI) and search `mcp`. - Cursor: See the Cursor MCP doc for the current location of the MCP tools list and OAuth Connect (labels such as Tools & MCP or MCP vary by version).
Command link encoding note
command:workbench.action.openSettings? links pass a JSON array argument (URL-encoded). Example: query mcp → ?%5B%22mcp%22%5D is ["mcp"]. Adjust the search string if the UI does not filter as expected (e.g. try "Tools MCP").
LaunchDarkly Onboarding Skill
End-to-end orchestrator that takes a project from "no LaunchDarkly anywhere" to a working first feature flag, with the SDK installed, MCP configured, and a durable summary doc left behind.
Why this exists
LaunchDarkly onboarding is a multi-step process that touches the editor, the package manager, the LaunchDarkly dashboard, the codebase, and the running app. Done by hand it takes 30-60 minutes and skips easily — agents tend to hardcode keys, install the wrong SDK, or forget to verify the flag actually works end-to-end.
This skill encodes the full workflow as a deterministic checklist with decision points and resumable state, so an agent can run it once and get the user to a "wow, that toggle just changed prod" moment without manual intervention at each step.
What it does
- Presents a friendly kickoff roadmap in chat so the user knows the arc before any code changes.
- Writes a working
LAUNCHDARKLY_ONBOARDING.mdlog so a new session or another agent can resume from the recorded next step. - Detects the project's language, framework, package manager, and existing LaunchDarkly usage.
- Detects the host coding agent (Cursor, Claude Code, Windsurf, Copilot, Codex) and installs the matching companion flag-management skills.
- Configures the LaunchDarkly hosted MCP server (OAuth) by handing off to `mcp-configure`.
- Installs and initializes the right SDK for the detected stack — server-side, browser, mobile, or edge — by handing off to `sdk-install` (which runs detect → plan → apply internally).
- Creates a first boolean feature flag, wires evaluation in code, and verifies the off → on → off cycle by handing off to `first-flag`.
- Replaces the working log with a permanent
LAUNCHDARKLY.mdsummary that documents the SDK, env vars, dashboard links, and AI agent integration.
It does not create flags before the SDK is installed, modify non-LaunchDarkly dependencies without explicit consent, hardcode SDK keys in source, or restructure the project.
Decision points
The workflow has explicit blocking decision points where the agent stops and asks the user a structured question:
| ID | Where | Question |
|---|---|---|
| D5 | Step 5 -- detect | Which SDK / which language / which package to integrate (monorepo, multi-language, no runnable app)? |
| D7 | Step 5 -- apply | How are secrets set up: user-specified location, user handles, or .env fallback? |
| D8 | Step 5 -- apply | Approval before changing non-LaunchDarkly dependencies. |
| D9 | Step 6 | Auth errors (401/403): stop, do not retry. |
These are tool-call decision points — the skill instructs the agent to use its native question tool (e.g. AskQuestion in Cursor) instead of writing the question as prose.
Installation
This skill is part of the launchdarkly/ai-tooling plugin and ships alongside `onboarding-router`, which routes generic "onboard me" requests into this skill (the Feature Flags path).
- Claude Code / Cursor: install the LaunchDarkly plugin and call
/onboarding, or just say "onboard me to LaunchDarkly" — the router picks this skill automatically when the request matches the flags path. - Other agents: copy
skills/onboarding/into your agent's skills path, ornpx skills add launchdarkly/ai-tooling --skill onboarding -y --agent <agent-id>.
Usage
Onboard me to LaunchDarklySet up LaunchDarkly in this Next.js project, project key is web-appContinue setting up LaunchDarkly(If a LAUNCHDARKLY_ONBOARDING.md log already exists, the skill resumes from the recorded next step instead of restarting.)
Structure
onboarding/
├── SKILL.md # main orchestrator workflow
├── README.md # this file
├── marketplace.json # plugin metadata
├── mcp-configure/ # nested skill: Step 4 (MCP)
├── sdk-install/ # nested skill: Step 5 (detect → plan → apply)
├── first-flag/ # nested skill: Step 6 (first flag)
└── references/
├── 1.8-summary.md # template for the permanent LAUNCHDARKLY.md
├── 1.9-editor-rules.md # editor rule / skill hooks per agent
└── sdk/
├── recipes.md # per-SDK install + init recipes
└── snippets/ # reusable code snippets per languageRelated
- Onboarding Router — picks this skill (or AgentControl / Experiments / Observability) based on user intent.
- `launchdarkly-flag-create` — installed during Step 3 and used optionally during Step 6.
- `launchdarkly-flag-discovery`, `launchdarkly-flag-targeting`, `launchdarkly-flag-cleanup` — companion flag-management skills installed in Step 3.
License
Apache-2.0
<!-- eval-score:start --> _Eval score not yet recorded._ <!-- eval-score:end -->
Onboarding Summary
After completing the onboarding flow, leave behind a summary document in the user's repository so they (and their team) have a reference for how LaunchDarkly was set up and what to do next.
Step 1: Generate the Summary Document
Create a file called LAUNCHDARKLY.md (or docs/LAUNCHDARKLY.md if the project has a docs/ directory) in the user's repository with the following sections. Fill in the details based on what was done during onboarding. Collect the LaunchDarkly project key and environment key ({PROJECT_KEY} / {ENV_KEY}) from the same place you used during onboarding (dashboard URLs, MCP tools, or Project settings → Environments) if they were not written into the plan explicitly.
Template
The wrapper below uses ~~~markdown so a nested `json block inside the template does not break Markdown rendering. (The generated LAUNCHDARKLY.md file itself may use normal ` fences.)
~~~markdown
LaunchDarkly Setup
This project uses LaunchDarkly for feature flag management.
SDK Details
- SDK: {SDK_NAME} ({SDK_PACKAGE})
- SDK Type: {server-side | client-side | mobile | edge}
- Key Type: {SDK Key | Client-side ID | Mobile Key}
- Installed via: {INSTALL_COMMAND}
- Initialization file: {ENTRYPOINT_FILE}
Configuration
The SDK key is configured via the {ENV_VAR_NAME} environment variable.
- Do not hardcode the SDK key in source code.
- Add the key to your
.envfile locally (already in.gitignore). - For production, set it in your deployment environment (e.g., CI/CD secrets, container env vars, cloud config).
Where to Find Things
| What | Where |
|---|---|
| Feature flags dashboard | https://app.launchdarkly.com/projects/{PROJECT_KEY}/flags |
| Project settings | https://app.launchdarkly.com/settings/projects/{PROJECT_KEY} |
| Environments | https://app.launchdarkly.com/settings/projects/{PROJECT_KEY}/environments |
| API access tokens | https://app.launchdarkly.com/settings/authorization |
| SDK documentation | {SDK_DOCS_URL} |
| LaunchDarkly docs | https://launchdarkly.com/docs |
How Feature Flags Work in This Project
1. Flags are evaluated using the LaunchDarkly SDK in {ENTRYPOINT_FILE} 2. Flag values are fetched from LaunchDarkly based on the evaluation context (user/device/org) 3. Changes to flags in the dashboard take effect immediately (server-side SDKs use streaming by default)
Example: Evaluating a Flag
{INSERT_LANGUAGE_SPECIFIC_EXAMPLE}
Next Steps
Here are some things you can do now that LaunchDarkly is set up:
Feature Flag Best Practices
- Use flags for every new feature: Wrap new features in flags so you can release and roll back independently of deployments.
- Clean up temporary flags: Mark flags as temporary during creation and archive them when no longer needed.
- Use descriptive flag keys: e.g.,
enable-checkout-v2instead offlag-1.
Advanced Capabilities
- [Percentage Rollouts](https://launchdarkly.com/docs/home/targeting-flags/rollouts) — Gradually roll out features to a percentage of users.
- [Targeting Rules](https://launchdarkly.com/docs/home/targeting-flags/targeting-rules) — Target specific users, segments, or contexts.
- [Experimentation](https://launchdarkly.com/docs/home/about-experimentation) — Run A/B tests and measure the impact of flag variations.
- [AI Configs](https://launchdarkly.com/docs/home/ai-configs) — Manage AI model configurations and prompts with feature flags.
- [Guarded Rollouts](https://launchdarkly.com/docs/home/guarded-rollouts) — Automatically roll back flag changes based on metric guardrails.
- [Observability](https://launchdarkly.com/docs/home/observability) — Monitor flag evaluations and SDK performance with built-in telemetry.
AI Agent Integration (MCP Server)
Install the LaunchDarkly MCP server to let your AI agent manage feature flags directly from your editor. With it, your agent can:
- Create and manage flags — Ask your agent to create a new feature flag, and it will handle the API calls for you.
- Toggle flags on/off — Turn features on or off across environments without leaving your editor.
- Set up targeting rules — Configure percentage rollouts, user targeting, and segment-based rules through natural language.
- Clean up stale flags — Ask your agent to find temporary flags that are fully rolled out and ready to archive.
- Run experiments — Set up A/B tests and monitor results through your agent.
- Manage AI configs — Update model configurations and prompts managed by LaunchDarkly.
Setup: Hosted MCP — uses OAuth; no tokens or API keys needed in config files. See the MCP server docs for editor-specific setup instructions.
Step 2: Fill in the Template
Replace all {PLACEHOLDER} values with the actual values from the onboarding session (gather any you did not write down earlier from Project settings → Environments in the LaunchDarkly dashboard or from MCP tools):
{SDK_NAME}: The human-readable SDK name (e.g., "Node.js Server SDK"){SDK_PACKAGE}: The package name (e.g.,@launchdarkly/node-server-sdk){INSTALL_COMMAND}: The install command used (e.g.,npm install @launchdarkly/node-server-sdk){ENTRYPOINT_FILE}: The file where initialization code was added{ENV_VAR_NAME}: The environment variable name used for the SDK key (or client-side ID env name){PROJECT_KEY}: The LaunchDarkly project key (used in dashboard URLs and MCP tool calls){ENV_KEY}: The LaunchDarkly environment key for the environment whose SDK key / client-side ID you used (e.g.,production,test,development) — used in dashboard URLs scoped per environment{SDK_DOCS_URL}: Link to the specific SDK documentation{INSERT_LANGUAGE_SPECIFIC_EXAMPLE}: A short code snippet showing flag evaluation in the project's language
Step 3: Commit the Summary
Add the file to version control so the whole team can reference it:
git add LAUNCHDARKLY.md
git commit -m "docs: add LaunchDarkly setup reference"Ask the user for permission before committing. If they prefer not to commit it, that's fine — they still have the file locally.
Editor Rules and Skills
After onboarding, do two things:
1. Ensure the user has the relevant LaunchDarkly agent skills installed — The goal is not “a plugin” in the abstract: the user (or agent) should have the same skills this repository ships, so future sessions can load them by name. Standard set (install all four):
launchdarkly-flag-createlaunchdarkly-flag-discoverylaunchdarkly-flag-targetinglaunchdarkly-flag-cleanup
Optional: onboarding (for more SDK onboarding later). Preferred: Install the LaunchDarkly plugin `launchdarkly@launchdarkly-ai-tooling` from [github.com/launchdarkly/ai-tooling](https://github.com/launchdarkly/ai-tooling), which packages these skills—then confirm in the UI or CLI that those skill names are available.
- Claude Code: After any required marketplace setup for that repo (see the repository README or
claude plugin/ Anthropic docs for your CLI version), install with:
claude plugin install launchdarkly@launchdarkly-ai-toolingIf the command name or flags differ in your build, use claude plugin --help and match the plugin coordinate above. Verify the four standard skills (above) show up as usable after install.
- Cursor: Install or enable skills from the same distribution per current Cursor docs (marketplace / plugin UI pointing at this repo or copied folders). Verify the four
launchdarkly-flag-*skills are listed or discoverable. - Fallback (no plugin): Copy skill directories from github.com/launchdarkly/ai-tooling (or this monorepo’s published plugin) into the user’s skills location so each folder contains a
SKILL.mdforlaunchdarkly-flag-create,launchdarkly-flag-discovery,launchdarkly-flag-targeting, andlaunchdarkly-flag-cleanup. Optional: include `onboarding` from this repo’s onboarding path. List any copied paths in the rules file so agents know where to readSKILL.md.
2. Write an editor rule — The rule must tell future agents to read and follow those skills for flag work. Do not bake in SDK documentation URLs; procedures and compatibility live in each skill’s SKILL.md. Deep links to SDK docs belong in LAUNCHDARKLY.md if you already created that summary.
Default skill set (feature flags)
Unless the user opts out, treat all of these as the standard kit and mention each one in the generated rule. They are published in github.com/launchdarkly/ai-tooling (same four skills as in step 1 above):
Skill name (frontmatter) | Purpose |
|---|---|
launchdarkly-flag-create | Create and configure flags and wire evaluation to match the codebase (MCP when required). |
launchdarkly-flag-discovery | Audit flag inventory, stale or launched flags, and removal readiness. |
launchdarkly-flag-targeting | Toggle flags, percentage rollouts, targeting rules, and promote config between environments. |
launchdarkly-flag-cleanup | Safely remove flags from code, readiness checks, and MCP-driven cleanup workflows. |
Adjust the table only if the user explicitly wants a smaller set.
Step 1: Detect the Editor
Check for editor configuration files in the project root:
| File/Directory | Editor |
|---|---|
.cursor/ or .cursorrules | Cursor |
.claude/ | Claude Code (Anthropic) |
.github/copilot-instructions.md | GitHub Copilot |
.vscode/ (without Cursor indicators) | VS Code |
.idea/ | JetBrains IDE — use For JetBrains (no dedicated template file path here) |
If you can't detect the editor, default to Claude Code and create .claude/rules/launchdarkly.md.
Step 2: Create the Rules File
Base the file on the templates below. Substitute project facts ({SDK_NAME}, {ENTRYPOINT_FILE}, {ENV_VAR_NAME}) from onboarding. Do not add {SDK_DOCS_URL} or a documentation links section to this file—that is intentionally omitted so agents rely on skills + MCP.
The rule text must explicitly say: when doing flag create, targeting, discovery, cleanup, or code removal, load the matching LaunchDarkly skill and execute its workflow (not just “see links”).
Shared body (use in Cursor and Claude Code)
Use this markdown block inside each template (Cursor: below the YAML frontmatter; Claude Code: from the first # heading).
# LaunchDarkly Feature Flags
This project uses LaunchDarkly for feature flag management.
## SDK context (this repo)
- SDK: {SDK_NAME}
- Initialization: {ENTRYPOINT_FILE}
- Key env var: {ENV_VAR_NAME} (never hardcode secrets in source)
## Agent: use LaunchDarkly skills (required)
Ensure the **LaunchDarkly** agent skills below are installed (`launchdarkly@launchdarkly-ai-tooling` plugin from [github.com/launchdarkly/ai-tooling](https://github.com/launchdarkly/ai-tooling), or equivalent copies on disk). For any substantive flag work, **open that skill’s `SKILL.md` and follow it**—do not improvise from generic flag advice alone.
| Skill | When to use it |
|-------|------------------|
| `launchdarkly-flag-create` | User wants a new flag, code wiring, feature toggle, or experiment setup. |
| `launchdarkly-flag-discovery` | User wants flag inventory, debt/stale-flag audit, health, or removal readiness. |
| `launchdarkly-flag-targeting` | User wants who sees a flag, rollouts, targeting rules, or environment promotion. |
| `launchdarkly-flag-cleanup` | User wants a flag removed from code safely, archive/cleanup workflows, or MCP-driven removal. |
**Invocation:** Match the user’s request to the skill `description` in each skill’s frontmatter, or use the editor’s slash / plugin command for that skill if configured.
**Tools:** When a skill lists LaunchDarkly MCP tools as required, use MCP; do not skip validation steps.
## Conventions (summary)
- Prefer boolean flags unless multivariate is required; use descriptive kebab-case keys (e.g. `enable-checkout-v2`).
- Always pass a fallback when evaluating flags; use a meaningful evaluation context (user key, org, etc.).
- Server-side SDK keys stay secret; client-side IDs may appear in browser code.
- Do not evaluate flags in tight loops without caching.
- Archive or remove flag code when a flag is fully rolled out and the team agrees—use `launchdarkly-flag-cleanup` (and `launchdarkly-flag-discovery` first if assessing candidates).For Cursor (.cursor/rules/launchdarkly.mdc)
Create .cursor/rules/launchdarkly.mdc:
---
description: LaunchDarkly feature flags — require LaunchDarkly agent skills for flag workflows
globs: []
alwaysApply: false
---
{PASTE_SHARED_BODY_HERE}Replace {PASTE_SHARED_BODY_HERE} with the shared body (no literal placeholder left in the file).
For Claude Code (.claude/rules/launchdarkly.md)
Create .claude/rules/launchdarkly.md containing only the shared body (no YAML frontmatter).
For GitHub Copilot (.github/copilot-instructions.md)
Append to .github/copilot-instructions.md (create if it doesn't exist). Copilot may not load external skills the same way; still steer toward the same workflows and name the skills:
## LaunchDarkly Feature Flags
This project uses LaunchDarkly ({SDK_NAME}) for feature flag management.
Initialization: {ENTRYPOINT_FILE}. SDK key / client ID: environment variable `{ENV_VAR_NAME}` only—never commit secrets.
For flag work, follow the LaunchDarkly agent skills when available: **`launchdarkly-flag-create`** (create + code), **`launchdarkly-flag-discovery`** (audit / inventory), **`launchdarkly-flag-targeting`** (rollouts / targeting / env promotion), **`launchdarkly-flag-cleanup`** (code removal / cleanup / MCP workflows). Read each skill’s instructions instead of guessing flag lifecycle steps.For JetBrains (IntelliJ, WebStorm, Rider, etc.)
There is no JetBrains-specific rules template in this reference (.idea/ only indicates the IDE family). Do not silently skip: tell the user you detected JetBrains and that they should rely on `LAUNCHDARKLY.md` (Onboarding Summary) plus installing `launchdarkly@launchdarkly-ai-tooling` (same as Claude Code) or copying skill folders manually.
Reasonable options to suggest:
- Keep flag workflow guidance in `LAUNCHDARKLY.md` and team docs the IDE already opens.
- If the team also uses GitHub Copilot in the same repo, reuse the For GitHub Copilot template above in
.github/copilot-instructions.mdso any tool that reads that file picks up the same guidance. - If their JetBrains AI plugin supports a project-level instruction file, paste the shared body there (adapt paths to your product’s docs)—this doc does not name a single standard path for all JetBrains products.
For other editors (not Cursor, Claude Code, Copilot, VS Code, or JetBrains)
If the editor doesn't have a rules system, skip creating a rules file. Rely on LAUNCHDARKLY.md and tell the user which LaunchDarkly skills to install (launchdarkly@launchdarkly-ai-tooling or copied skill folders from github.com/launchdarkly/ai-tooling).
Step 3: Fill in the Placeholders
From the onboarding session, set:
{SDK_NAME}— e.g.Node.js Server SDK{ENTRYPOINT_FILE}— e.g.src/index.ts{ENV_VAR_NAME}— e.g.LAUNCHDARKLY_SDK_KEY
Do not add documentation URLs to this rules file. If you need SDK doc links for humans, put them only in LAUNCHDARKLY.md (Onboarding Summary).
If you added or removed skills from the default table (user request), update the skill table in the shared body to match.
Step 4: Commit the Rules
# Claude Code (most common for this skill)
git add .claude/rules/launchdarkly.md
# Cursor
git add .cursor/rules/launchdarkly.mdc
# GitHub Copilot / shared instructions
git add .github/copilot-instructions.md
# Add only the file(s) you created or changed, then:
git commit -m "chore: add LaunchDarkly feature flag management rules"Ask the user for permission before committing.
SDK Recipes
Use this reference to match a detected tech stack to the correct LaunchDarkly SDK.
Field | Value tables in this file are the index layer: package name, what to look for in the repo (detect files/patterns), a one-line install hint, and the official Docs link. Use them first to choose the right SDK and command—before opening a detail file.
Each recipe links to an SDK detail file under `snippets/`. Open that file for curated links to official docs, samples, and package registries. Ten of those files also include a copy-paste onboarding sample; the rest are pointer-only—follow LaunchDarkly's docs for install and initialization. Never commit real keys. Treat each Docs link in the table as canonical for API details and migrations.
Source of truth: Official LaunchDarkly SDK documentation is authoritative. Prefer each recipe's Docs link over summaries here.
Top 10 SDKs (start here)
These are the most common stacks—check here first before scanning less common SDKs below.
React (Web)
| Field | Value |
|---|---|
| Package | launchdarkly-react-client-sdk |
| Detect files | package.json |
| Detect patterns | react, react-dom, "react": |
| Install | npm install launchdarkly-react-client-sdk |
| Flag key behavior | camelCase by default. useFlags() transforms my-flag-key → myFlagKey. Disable with reactOptions: { useCamelCaseFlagKeys: false } on the provider. When wiring first-flag code, use the camelCased form unless the project disables it. |
| Docs | React SDK reference · React Web SDK reference |
SDK detail: `snippets/react-web-sdk.md` (includes onboarding sample)
API: Prefer `asyncWithLDProvider` with `timeout` (seconds; recommend 1–5) so the app renders after the JS client initializes; alternatively `withLDProvider` if you initialize after mount. See Initialize the client.
Next.js: If next is present, this client recipe covers browser/client-component flows; server routes and Server Components usually also need [Node.js (Server)](#nodejs-server) and an SDK key there—see the Next.js note under that recipe and Generate integration plan.
JavaScript (Browser)
| Field | Value |
|---|---|
| Package | @launchdarkly/js-client-sdk |
| Detect files | package.json, index.html |
| Detect patterns | webpack, vite, parcel, rollup; use when not using React / Vue wrappers |
| Install | npm install @launchdarkly/js-client-sdk |
| Docs | JavaScript SDK reference |
SDK detail: `snippets/javascript-browser-sdk.md` (includes onboarding sample)
API vs. other SDKs: The current browser package is `@launchdarkly/js-client-sdk`: `createClient`, `start()`, then `waitForInitialization({ timeout })` (check result.status). See the browser SDK API docs. The legacy npm name launchdarkly-js-client-sdk (v3) used `initialize()` without start()—do not mix that flow with v4.
Node.js (Server)
| Field | Value |
|---|---|
| Package | @launchdarkly/node-server-sdk |
| Detect files | package.json |
| Detect patterns | express, fastify, koa, hapi, nestjs, next (API routes), "type": "module" |
| Install | npm install @launchdarkly/node-server-sdk |
| Docs | Node.js SDK reference (server-side) |
SDK detail: `snippets/node-server-sdk.md` (includes onboarding sample)
Next.js: next in Detect patterns only signals that the server-side Node SDK may apply (API routes / Route Handlers, Server Components, server-only code). Client components in the browser still need the [React (Web)](#react-web) recipe (launchdarkly-react-client-sdk and a client-side ID)—do not silently pick only the Node server SDK for a full-stack Next app. Plan one or both SDKs depending on where flags are evaluated; align with Generate integration plan (Next.js callout there).
Python (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-server-sdk (PyPI) |
| Detect files | requirements.txt, pyproject.toml, setup.py, Pipfile |
| Detect patterns | flask, django, fastapi, starlette |
| Install | pip install launchdarkly-server-sdk — optional: pip install launchdarkly-observability (requires SDK 9.12+; see Install the SDK) |
| Docs | Python SDK reference |
SDK detail: `snippets/python-server-sdk.md` (includes onboarding sample)
API: `ldclient.set_config(Config(sdk_key))` then `client = ldclient.get()` (singleton). Optional `plugins=[ObservabilityPlugin()]` on `Config` with `launchdarkly-observability`. Forked workers: `postfork()`. See Initialize the client.
React Native
| Field | Value |
|---|---|
| Package | @launchdarkly/react-native-client-sdk |
| Detect files | package.json |
| Detect patterns | react-native |
| Install | npm install @launchdarkly/react-native-client-sdk |
| Flag key behavior | camelCase by default. Same behavior as React Web: useFlags() transforms my-flag-key → myFlagKey. Disable with reactOptions: { useCamelCaseFlagKeys: false }. |
| Docs | React Native SDK reference |
SDK detail: `snippets/react-native-sdk.md` (includes onboarding sample)
API: `@launchdarkly/react-native-client-sdk` v10 — `ReactNativeLDClient` (mobile key) + `LDProvider` + `identify(context)` on mount. Non-Expo: add `@react-native-async-storage/async-storage` and `npx pod-install`. See React Native SDK reference.
.NET (Server)
| Field | Value |
|---|---|
| Package | LaunchDarkly.ServerSdk (NuGet) |
| Detect files | *.csproj, *.sln, *.fsproj (look for BlazorWebAssembly, blazorwasm, UseBlazorWebAssembly, blazorserver, or Microsoft.AspNetCore.Components / Blazor in the project) |
| Detect patterns | Microsoft.AspNetCore, Microsoft.NET, Blazor, blazor, blazorserver (host/server UI—not WASM-only client projects) |
| Install | dotnet add package LaunchDarkly.ServerSdk — optional: dotnet add package LaunchDarkly.Observability (requires server SDK 8.10+; see Install the SDK) |
| Docs | .NET SDK reference (server-side) |
SDK detail: `snippets/dotnet-server-sdk.md` (includes onboarding sample)
API (current docs): `LaunchDarkly.Sdk` / `LaunchDarkly.Sdk.Server` — build config with `Configuration.Builder(sdkKey).StartWaitTime(...).Build()`, then `new LdClient(config)` before `WebApplication.CreateBuilder` → `Build()`. Prefer `LdClient` as a singleton in DI for real services. See Initialize the client.
Blazor: Blazor Server (and other server-hosted Blazor where .NET runs on the server) → this server-side SDK and an SDK key. Blazor WebAssembly runs in the browser → use [.NET (Client)](#net-client) (LaunchDarkly.ClientSdk, Client-side ID). Inspect .csproj / SDK props: WASM projects typically use the Blazor WebAssembly workload or blazorwasm / UseBlazorWebAssembly; do not treat those as server-only.
Java (Server)
| Field | Value |
|---|---|
| Package | com.launchdarkly:launchdarkly-java-server-sdk (Maven Central) |
| Detect files | pom.xml, build.gradle, build.gradle.kts, *.kt (JVM services—see note below) |
| Detect patterns | spring, quarkus, micronaut, dropwizard, kotlin, ktor, org.jetbrains.kotlin |
| Install | Maven (pom.xml) and Gradle (Groovy / Kotlin DSL)—see Install (Maven and Gradle) below; pin version from SDK releases |
| Docs | Java SDK reference |
SDK detail: `snippets/java-server-sdk.md` (includes onboarding sample)
Install (Maven and Gradle): Install the SDK shows XML for Maven and Gradle coordinates. Match your build file (pom.xml, build.gradle, or build.gradle.kts). Example Gradle shortcut: implementation 'com.launchdarkly:launchdarkly-java-server-sdk:7.+' or implementation("com.launchdarkly:launchdarkly-java-server-sdk:7.+").
API: *`import com.launchdarkly.sdk.** / **com.launchdarkly.sdk.server.` — `new LDClient(sdkKey)` (default startup wait), `isInitialized()`*. See Initialize the client.
Kotlin (JVM) backends: For Ktor, Spring Boot + Kotlin, or other server-side Kotlin on the JVM, use this Java server SDK (launchdarkly-java-server-sdk) from Kotlin code—LaunchDarkly does not ship a separate Kotlin server artifact. build.gradle.kts plus .kt sources without Android-only signals should still match here. Android apps (Kotlin or Java) that talk to LaunchDarkly from the device use the [Android](#android) client SDK recipe, not this server SDK.
Go (Server)
| Field | Value |
|---|---|
| Package | github.com/launchdarkly/go-server-sdk/v7 |
| Detect files | go.mod, go.sum |
| Detect patterns | net/http, gin, echo, fiber, chi |
| Install | go get github.com/launchdarkly/go-server-sdk/v7 |
| Docs | Go SDK reference |
SDK detail: `snippets/go-server-sdk.md` (includes onboarding sample)
Swift / iOS
| Field | Value |
|---|---|
| Package | LaunchDarkly (CocoaPods; SPM / Carthage via GitHub) |
| Detect files | Package.swift, Podfile, Cartfile, *.xcodeproj |
| Detect patterns | UIKit, SwiftUI, ios |
| Install | SPM, CocoaPods, or Carthage — see Install the SDK and `ios-client-sdk.md`; pin versions from SDK releases |
| Docs | iOS SDK reference · Set up iOS SDK (onboarding) |
SDK detail: `snippets/ios-client-sdk.md` (includes onboarding sample)
API: `LDConfig(mobileKey:autoEnvAttributes:)`, `LDContextBuilder`, `LDClient.start(…, startWaitSeconds:completion:)` — see Initialize the client. Optional `LaunchDarklyObservability` (v9.14+).
Android
| Field | Value |
|---|---|
| Package | com.launchdarkly:launchdarkly-android-client-sdk |
| Detect files | build.gradle, build.gradle.kts, AndroidManifest.xml |
| Detect patterns | android, com.android, androidx |
| Install | See Install (two Gradle DSLs) below — same artifact, different syntax for Groovy vs Kotlin DSL |
| Docs | Android SDK reference |
Install (two Gradle DSLs): The Install the SDK topic shows both forms. Use the one that matches the app module file you have:
- Gradle Groovy (
build.gradle):implementation 'com.launchdarkly:launchdarkly-android-client-sdk:5.+' - Gradle Kotlin DSL (
build.gradle.kts):implementation("com.launchdarkly:launchdarkly-android-client-sdk:5.+")
SDK detail: `snippets/android-client-sdk.md` (includes onboarding sample)
---
Server-side SDKs (other)
Server-side SDKs use an SDK Key and are intended for backends where the key stays secret.
The five most-used server runtimes (Node.js, Python, .NET, Java, Go) are in [Top 10 SDKs (start here)](#top-10-sdks-start-here) above.
Apex (Salesforce)
| Field | Value |
|---|---|
| Package | Deploy from apex-server-sdk (no NuGet/Maven module) |
| Detect files | sfdx-project.json, force-app, *.cls |
| Detect patterns | salesforce, Salesforce, Apex |
| Install | Follow the docs (SFDX deploy and LaunchDarkly Salesforce bridge) |
| Docs | Apex SDK reference |
SDK detail: `snippets/apex-server-sdk.md`
C++ (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-cpp-server (via CMake FetchContent, vcpkg, or vendor) |
| Detect files | CMakeLists.txt, Makefile, *.cpp, *.h |
| Detect patterns | cmake, server-side C++ services |
| Install | See docs (CMake / vcpkg) |
| Docs | C++ SDK reference (server-side) |
SDK detail: `snippets/cpp-server-sdk.md`
Erlang / Elixir
| Field | Value |
|---|---|
| Package | Erlang: launchdarkly_server_sdk (Hex). Elixir: add the same dependency in mix.exs |
| Detect files | rebar.config, mix.exs |
| Detect patterns | erlang, elixir, phoenix |
| Install | Rebar or Mix per docs |
| Docs | Erlang SDK reference |
SDK detail: `snippets/erlang-server-sdk.md`
Haskell (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-server-sdk (Cabal / Stack / Hackage) |
| Detect files | *.cabal, stack.yaml, package.yaml |
| Detect patterns | haskell, cabal, stack |
| Install | Add dependency per docs |
| Docs | Haskell SDK reference |
SDK detail: `snippets/haskell-server-sdk.md`
Lua (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-server-sdk (LuaRocks) |
| Detect files | *.lua, *.rockspec |
| Detect patterns | lua, luarocks, OpenResty / NGINX / HAProxy Lua |
| Install | luarocks install launchdarkly-server-sdk (see docs for your runtime) |
| Docs | Lua SDK reference |
SDK detail: `snippets/lua-server-sdk.md`
PHP (Server)
| Field | Value |
|---|---|
| Package | launchdarkly/server-sdk |
| Detect files | composer.json |
| Detect patterns | laravel, symfony, slim |
| Install | composer require launchdarkly/server-sdk |
| Docs | PHP SDK reference |
SDK detail: `snippets/php-server-sdk.md`
Ruby (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-server-sdk |
| Detect files | Gemfile, *.gemspec |
| Detect patterns | rails, sinatra, hanami |
| Install | gem install launchdarkly-server-sdk or add to Gemfile |
| Docs | Ruby SDK reference |
SDK detail: `snippets/ruby-server-sdk.md`
Rust (Server)
| Field | Value |
|---|---|
| Package | launchdarkly-server-sdk |
| Detect files | Cargo.toml |
| Detect patterns | actix, rocket, axum, warp |
| Install | cargo add launchdarkly-server-sdk |
| Docs | Rust SDK reference |
SDK detail: `snippets/rust-server-sdk.md`
---
Client-side SDKs (other)
Client-side SDKs use a Client-side ID for browser and desktop clients where that credential is expected to be visible in the app. Use the linked reference for bootstrap, privacy, and flag delivery behavior.
React (Web) and JavaScript (browser) are in [Top 10 SDKs (start here)](#top-10-sdks-start-here) above.
Vue
| Field | Value |
|---|---|
| Package | launchdarkly-vue-client-sdk |
| Detect files | package.json |
| Detect patterns | vue, "vue": |
| Install | npm install launchdarkly-vue-client-sdk |
| Docs | Vue SDK reference |
SDK detail: `snippets/vue-client-sdk.md`
Angular, Svelte, Preact, and other browser frameworks
| Field | Value |
|---|---|
| Package | @launchdarkly/js-client-sdk |
| Detect files | package.json, angular.json, svelte.config.js |
| Detect patterns | @angular, svelte, preact |
| Install | npm install @launchdarkly/js-client-sdk |
| Docs | JavaScript SDK reference (no dedicated SDK; use the JS client) |
SDK detail: `snippets/browser-frameworks-sdk.md`
API: Same package and `createClient` / `start()` / `waitForInitialization` flow as JavaScript (Browser). Prefer `javascript-browser-sdk.md` for a copy-paste sample.
.NET (Client)
| Field | Value |
|---|---|
| Package | LaunchDarkly.ClientSdk |
| Detect files | *.csproj, *.sln (WASM: blazorwasm, BlazorWebAssembly, UseBlazorWebAssembly in project) |
| Detect patterns | Xamarin, MAUI, WPF, UWP, Avalonia, Blazor, blazor, blazorwasm |
| Install | dotnet add package LaunchDarkly.ClientSdk |
| Docs | .NET SDK reference (client-side) |
SDK detail: `snippets/dotnet-client-sdk.md`
Keys: MAUI, Xamarin, WPF, UWP (and similar native/desktop shells) use this package as LaunchDarkly’s .NET mobile client SDK with a mobile key. Blazor WebAssembly (browser-hosted UI) uses the same package with a Client-side ID. Blazor Server (and server-rendered interactive Blazor) → [.NET (Server)](#net-server) with LaunchDarkly.ServerSdk. See Generate integration plan.
C++ (Client)
| Field | Value |
|---|---|
| Package | launchdarkly-cpp-client (CMake / vcpkg per docs) |
| Detect files | CMakeLists.txt, Makefile, *.cpp, *.h |
| Detect patterns | Desktop or embedded C++ clients |
| Install | See docs |
| Docs | C++ SDK reference (client-side) |
SDK detail: `snippets/cpp-client-sdk.md`
Electron
| Field | Value |
|---|---|
| Package | launchdarkly-electron-client-sdk |
| Detect files | package.json |
| Detect patterns | electron |
| Install | npm install launchdarkly-electron-client-sdk |
| Docs | Electron SDK reference |
SDK detail: `snippets/electron-client-sdk.md`
Node.js (Client)
| Field | Value |
|---|---|
| Package | launchdarkly-node-client-sdk |
| Detect files | package.json |
| Detect patterns | Node scripts or desktop tooling without Electron (see Electron above) |
| Install | npm install launchdarkly-node-client-sdk |
| Docs | Node.js SDK reference (client-side) |
SDK detail: `snippets/node-client-sdk.md`
Roku (BrightScript)
| Field | Value |
|---|---|
| Package | roku-client-sdk (GitHub releases) |
| Detect files | manifest, *.brs, SceneGraph *.xml |
| Detect patterns | brightscript, roku, SceneGraph |
| Install | Add SDK components per docs |
| Docs | Roku SDK reference |
SDK detail: `snippets/roku-client-sdk.md`
---
Mobile SDKs (other)
These entries are mobile or app-embedded targets. Most use a Mobile key; Flutter web is an exception (see below). Each Docs link points at the official reference (same pages as the client-side SDK family on launchdarkly.com/docs).
Swift / iOS, Android, and React Native are in [Top 10 SDKs (start here)](#top-10-sdks-start-here) above.
Flutter
LaunchDarkly documents this as the Flutter client SDK (launchdarkly_flutter_client_sdk); it is listed here because iOS, Android, and typical desktop app builds use a Mobile key.
| Field | Value |
|---|---|
| Package | launchdarkly_flutter_client_sdk |
| Detect files | pubspec.yaml |
| Detect patterns | flutter |
| Install | flutter pub add launchdarkly_flutter_client_sdk |
| Docs | Flutter SDK reference |
SDK detail: `snippets/flutter-client-sdk.md`
Keys: Mobile key for iOS, Android, and typical desktop app targets; Client-side ID (and your bundler’s public env pattern) for Flutter web. Multi-target apps may need separate config per surface—see Generate integration plan.
---
Edge SDKs
Edge SDKs run on edge platforms and use an SDK Key (see each platform's reference for environment and constraints).
| Platform | Detect pattern | Docs |
|---|---|---|
| Akamai EdgeWorkers | bundle.json, edgeworkers | Akamai SDK reference |
| Cloudflare Workers | wrangler.toml, @cloudflare/workers-types | Cloudflare SDK reference |
| Fastly Compute | Fastly service config, @fastly/js-compute (per your stack) | Fastly SDK reference |
| Vercel Edge | vercel.json with edge functions, @vercel/edge | Vercel SDK reference |
SDK detail: `snippets/edge-sdks.md` (all edge platforms)
---
Android — SDK detail
- Official docs: Android SDK reference · Set up Android SDK (onboarding)
- Recipe (detect / install): SDK Recipes (Android)
Install the dependency: Install the SDK documents two Gradle styles—the same Maven coordinate, different syntax. Pick the one that matches your app module:
// Gradle Groovy — typically app/build.gradle
implementation 'com.launchdarkly:launchdarkly-android-client-sdk:5.+'// Gradle Kotlin DSL — typically app/build.gradle.kts
implementation("com.launchdarkly:launchdarkly-android-client-sdk:5.+")Import the SDK: Use the imports that match your language (Import the SDK). Observability is optional (separate launchdarkly-observability-android dependency; requires Android client SDK v5.9+).
Kotlin:
import com.launchdarkly.sdk.*
import com.launchdarkly.sdk.android.*
// Optional observability plugin, requires LaunchDarkly Android Client SDK v5.9+
// import com.launchdarkly.observability.plugin.Observability
// import com.launchdarkly.sdk.android.integrations.PluginJava:
import com.launchdarkly.sdk.*;
import com.launchdarkly.sdk.android.*;
// Optional observability plugin, requires LaunchDarkly Android Client SDK v5.9+
// import com.launchdarkly.observability.plugin.Observability;
// import com.launchdarkly.sdk.android.integrations.Plugin;The init snippet below matches the onboarding initialization example: use a placeholder mobile key first, then wire a real value from build configuration (see optional Gradle section). BuildConfig.LAUNCHDARKLY_MOBILE_KEY is not defined unless you add buildConfigField yourself—do not paste it without the Gradle setup.
Includes: Copy-paste onboarding sample below (Kotlin). Place inside your Application subclass (for example onCreate()); this refers to that Application instance.
import com.launchdarkly.sdk.*
import com.launchdarkly.sdk.android.*
// Optional observability plugin, requires LaunchDarkly Android Client SDK v5.9+
// import com.launchdarkly.observability.plugin.Observability
// import com.launchdarkly.sdk.android.integrations.Plugin
val ldConfig = LDConfig.Builder(AutoEnvAttributes.Enabled)
.mobileKey("YOUR_MOBILE_KEY")
.build()
// A "context" is a data object representing users, devices, organizations, and other entities.
val context = LDContext.create("EXAMPLE_CONTEXT_KEY")
// If you don't want to block execution while the SDK tries to get
// latest flags, move this code into an async IO task and await on its completion.
val client: LDClient = LDClient.init(this, ldConfig, context, 5)Replace "YOUR_MOBILE_KEY" with your Mobile key from LaunchDarkly Project settings > Environments (see Apply: environment configuration). Never commit real keys in source.
Optional — `BuildConfig` + Gradle (Kotlin DSL): Enable BuildConfig and pass the key from a non-committed gradle.properties or local.properties value:
// app/build.gradle.kts — excerpt
android {
buildFeatures {
buildConfig = true
}
defaultConfig {
val key = (project.findProperty("LAUNCHDARKLY_MOBILE_KEY") as String?)?.trim().orEmpty()
buildConfigField("String", "LAUNCHDARKLY_MOBILE_KEY", "\"$key\"")
}
}Then change .mobileKey("YOUR_MOBILE_KEY") to .mobileKey(BuildConfig.LAUNCHDARKLY_MOBILE_KEY) and set LAUNCHDARKLY_MOBILE_KEY=… where Gradle can read it (for example ~/.gradle/gradle.properties or a CI secret), not in a committed file.
Apex (Salesforce) — SDK detail
Primary: Apex SDK reference — deployment (SFDX), Salesforce bridge, initialization, and API.
Also useful:
- GitHub: apex-server-sdk
- Sample: hello-apex-server
Recipe (detect / install summary): SDK Recipes — Apex (Salesforce)
There is no bundled onboarding code sample in this repo for Apex; follow the official reference.
Angular, Svelte, Preact, and other browser frameworks — SDK detail
LaunchDarkly does not ship separate SDKs for every SPA framework. Use the JavaScript (browser) SDK and follow its reference for install, initialization, and evaluation.
Primary: JavaScript SDK reference
Onboarding sample (JS browser) in this repo: `javascript-browser-sdk.md`
Also useful:
- npm: launchdarkly-js-client-sdk
- GitHub: js-client-sdk
- API docs: JavaScript SDK API
Recipe (detect / install summary): SDK Recipes — Angular, Svelte, Preact, and other browser frameworks
C++ (Client) — SDK detail
Primary: C++ SDK reference (client-side) — CMake, vcpkg, initialization, and API.
Also useful:
- GitHub: cpp-sdks / client-sdk
- Samples: hello-c-client, hello-cpp-client
- API docs: C++ client SDK API
Recipe (detect / install summary): SDK Recipes — C++ (Client)
There is no bundled onboarding code sample in this repo for C++ client; follow the official reference.
C++ (Server) — SDK detail
Primary: C++ SDK reference (server-side) — CMake, vcpkg, initialization, and API.
Also useful:
- GitHub: cpp-sdks
- API docs: C/C++ server SDK API
Recipe (detect / install summary): SDK Recipes — C++ (Server)
There is no bundled onboarding code sample in this repo for C++ server; follow the official reference.
.NET (Client) — SDK detail
Same NuGet package (LaunchDarkly.ClientSdk) is used for mobile-style apps (MAUI, Xamarin, WPF, UWP, etc.) with a mobile key and for Blazor WebAssembly / browser-hosted UI with a Client-side ID. See Generate integration plan.
Primary: .NET SDK reference (client-side) — NuGet, initialization, and API.
Also useful:
- NuGet: LaunchDarkly.ClientSdk
- GitHub: .NET client SDK
- Sample: hello-dotnet-client
- API docs: .NET client SDK API
Recipe (detect / install summary): SDK Recipes — .NET (Client)
There is no bundled onboarding code sample in this repo for .NET client; follow the official reference.
.NET (Server) — SDK detail
- Official docs: .NET SDK reference (server-side)
- API reference: Server SDK API
- Published package: LaunchDarkly.ServerSdk (NuGet)
- Recipe (detect / install): SDK Recipes (.NET Server)
Target the current major server SDK on NuGet (LaunchDarkly.ServerSdk); follow the docs for version compatibility (.NET SDK reference).
Install: From the project directory (Install the SDK):
dotnet add package LaunchDarkly.ServerSdkOptional observability (.NET observability) — requires server SDK 8.10+:
dotnet add package LaunchDarkly.ObservabilityImport: Namespace differs from the package name (same page — import):
using LaunchDarkly.Sdk;
using LaunchDarkly.Sdk.Server;
// Optional — LaunchDarkly.Observability package; requires server SDK 8.10+
// using LaunchDarkly.Observability;Initialize: Use `Configuration.Builder(sdkKey)` with `StartWaitTime` (docs recommend a short wait so a bad network does not hang forever). Construct `LdClient` before `builder.Build()` (Initialize the client). In production, register `LdClient` as a singleton in DI instead of creating one per request.
Includes: Minimal ASP.NET Core Program.cs–style sample. SDK key: `LAUNCHDARKLY_SDK_KEY` (Apply: environment configuration).
using LaunchDarkly.Sdk;
using LaunchDarkly.Sdk.Server;
var builder = WebApplication.CreateBuilder(args);
var sdkKey = Environment.GetEnvironmentVariable("LAUNCHDARKLY_SDK_KEY");
if (string.IsNullOrWhiteSpace(sdkKey))
{
Console.Error.WriteLine(
"LAUNCHDARKLY_SDK_KEY is not set. Use Project settings > Environments > SDK key.");
Environment.Exit(1);
}
var ldConfig = Configuration.Builder(sdkKey)
.StartWaitTime(TimeSpan.FromSeconds(5))
.Build();
// Construct the client before Build() per LaunchDarkly docs.
using var ldClient = new LdClient(ldConfig);
var app = builder.Build();
if (!ldClient.Initialized)
{
Console.Error.WriteLine("LaunchDarkly client did not initialize within StartWaitTime.");
Environment.Exit(1);
}
// For onboarding only — events are normally flushed in the background.
ldClient.Flush();
Console.WriteLine("LaunchDarkly client ready.");
// app.MapGet(...);
app.Run();Optional — observability (SDK 8.10+): After adding `LaunchDarkly.Observability`, follow the `ObservabilityPlugin.Builder(builder.Services)` example in Initialize the client inside `Configuration.Builder`’s `Plugins` chain.
Edge SDKs — SDK detail
Edge SDKs use an SDK Key. Use the platform-specific reference for constraints (e.g. KV, environment, bundling).
| Platform | Detect pattern | Official docs | Package / repo |
|---|---|---|---|
| Akamai EdgeWorkers | bundle.json, edgeworkers | Akamai SDK reference | js-core / akamai-edgekv · API docs |
| Cloudflare Workers | wrangler.toml, @cloudflare/workers-types | Cloudflare SDK reference | js-core / cloudflare · API docs |
| Fastly Compute | Fastly config, @fastly/js-compute (typical) | Fastly SDK reference | js-core / fastly · API docs |
| Vercel Edge | vercel.json with edge functions, @vercel/edge | Vercel SDK reference | js-core / vercel · API docs |
Recipe index: SDK Recipes — Edge SDKs
There are no bundled onboarding code samples in this repo for edge SDKs; follow each platform’s official reference.
Electron — SDK detail
Primary: Electron SDK reference — npm install, initialization, and API.
Also useful:
- npm: launchdarkly-electron-client-sdk
- GitHub: electron-client-sdk
- Sample: hello-electron
- API docs: Electron SDK API
Recipe (detect / install summary): SDK Recipes — Electron
There is no bundled onboarding code sample in this repo for Electron; follow the official reference.
Erlang / Elixir — SDK detail
Primary: Erlang SDK reference — Rebar, Mix, initialization, and API.
Also useful:
- Hex package: launchdarkly_server_sdk
- GitHub: erlang-server-sdk
- Samples: hello-elixir, hello-phoenix
Recipe (detect / install summary): SDK Recipes — Erlang / Elixir
There is no bundled onboarding code sample in this repo for Erlang/Elixir; follow the official reference.
Flutter — SDK detail
Official docs are the Flutter client SDK (launchdarkly_flutter_client_sdk). Use a mobile key for typical iOS, Android, and desktop app builds; use a Client-side ID (and public env naming for web) for Flutter web. Multi-target apps: see Generate integration plan.
Primary: Flutter SDK reference — pubspec, initialization, and API.
Also useful:
- pub.dev: launchdarkly_flutter_client_sdk
- GitHub: flutter-client-sdk
- Example app: flutter_client_sdk example
- API docs: Flutter SDK API
Recipe (detect / install summary): SDK Recipes — Flutter
There is no bundled onboarding code sample in this repo for Flutter; follow the official reference.
Go (Server) — SDK detail
- Official docs: Go SDK reference
- API reference: `LDClient`, `MakeClient`
- Recipe (detect / install): SDK Recipes (Go Server)
The Initialize the client chapter shows `MakeClient` / `MakeCustomClient` (and optional `ldcontext` + `NewScopedClient` for a scoped client). It does not use `Initialized()` in that section. The `error` from `MakeClient` is what signals construction-time failure (see the “Best practices for error handling” callout in those docs). If you need to branch on “fully ready” after the timeout window, use [`Initialized`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk/v7#LDClient.Initialized) or [Monitoring SDK status](https://launchdarkly.com/docs/sdk/features/monitoring#go)—read [`MakeClient`](https://pkg.go.dev/github.com/launchdarkly/go-server-sdk/v7#MakeClient) for how the timeout interacts with returning before the client has finished connecting.
Includes: Minimal onboarding sample aligned with “Go SDK, using LDClient and default configuration” in the docs. For `MakeCustomClient`, `ldcontext`, `LDScopedClient`, or the observability plugin, follow the same page’s larger examples.
package main
import (
"fmt"
"os"
"time"
ld "github.com/launchdarkly/go-server-sdk/v7"
)
func main() {
ldClient, err := ld.MakeClient(os.Getenv("LAUNCHDARKLY_SDK_KEY"), 5*time.Second)
if err != nil {
fmt.Fprintf(os.Stderr, "failed to create LaunchDarkly client: %v\n", err)
os.Exit(1)
}
fmt.Println("LaunchDarkly client created.")
// For onboarding purposes only we flush events as soon as
// possible so we quickly detect your connection.
// You don't have to do this in practice because events are automatically flushed.
ldClient.Flush()
}Haskell (Server) — SDK detail
Primary: Haskell SDK reference — Cabal/Stack, initialization, and API.
Also useful:
- Hackage: launchdarkly-server-sdk
- GitHub: haskell-server-sdk
- Sample: hello-haskell-server
- API docs: Haskell SDK API
Recipe (detect / install summary): SDK Recipes — Haskell (Server)
There is no bundled onboarding code sample in this repo for Haskell; follow the official reference.
Swift / iOS — SDK detail
- Official docs: iOS SDK reference · Set up iOS SDK (onboarding)
- API reference: iOS SDK API docs
- Recipe (detect / install): SDK Recipes (Swift / iOS)
Why this differs from the home onboarding page: Set up iOS SDK uses a `"YOUR_MOBILE_KEY"` literal and a linear script. This skill keeps the same `LDConfig` / `LDContextBuilder` / `LDClient.start`…`startWaitSeconds` flow as Initialize the client, but resolves the mobile key from Xcode scheme env or Info.plist so archives are not missing the key. Substituting LDConfig(mobileKey: "YOUR_MOBILE_KEY", …) matches the docs verbatim when you only need a quick local paste.
Install the SDK: LaunchDarkly documents Swift Package Manager, CocoaPods, and Carthage (Install the SDK). Pin versions from the SDK releases page; the examples below follow the onboarding install style.
Swift Package Manager (Package.swift excerpt):
// ...
dependencies: [
.package(url: "https://github.com/launchdarkly/ios-client-sdk.git", .upToNextMajor("9.15.0")),
// Optional observability — iOS SDK v9.14+; see reference Install the SDK
// .package(url: "https://github.com/launchdarkly/swift-launchdarkly-observability.git", .upToNextMajor("1.0.0")),
],
targets: [
.target(
name: "YOUR_TARGET",
dependencies: ["LaunchDarkly"]
),
]
// ...CocoaPods (Podfile):
use_frameworks!
target 'YourTargetName' do
pod 'LaunchDarkly', '~> 9.15'
# Optional — LaunchDarklyObservability, iOS SDK v9.14+
# pod 'LaunchDarklyObservability', '~> 1.0'
endCarthage (Cartfile):
github "launchdarkly/ios-client-sdk" ~> 9.15Import (Import the SDK):
import LaunchDarkly
// Optional observability — iOS SDK v9.14+
// import LaunchDarklyObservabilityMobile key: Never ship a real key in source. ProcessInfo.processInfo.environment is set from the Xcode scheme for local runs; TestFlight / App Store builds need Info.plist (e.g. LaunchDarklyMobileKey) or xcconfig. Logical name: Apply: environment configuration.
Includes: Call configureLaunchDarkly() from application(_:didFinishLaunchingWithOptions:) (UIKit) or your SwiftUI startup path.
import LaunchDarkly
func configureLaunchDarkly() {
let mobileKey: String?
if let v = ProcessInfo.processInfo.environment["LAUNCHDARKLY_MOBILE_KEY"], !v.isEmpty {
mobileKey = v
} else if let v = Bundle.main.object(forInfoDictionaryKey: "LaunchDarklyMobileKey") as? String, !v.isEmpty {
mobileKey = v
} else {
mobileKey = nil
}
guard let mobileKey else {
print("LaunchDarkly: missing mobile key (scheme LAUNCHDARKLY_MOBILE_KEY for Xcode runs, or Info.plist LaunchDarklyMobileKey for archives).")
return
}
let config = LDConfig(mobileKey: mobileKey, autoEnvAttributes: .enabled)
// Optional observability — iOS SDK v9.14+; add package/pod and set config.plugins per
// https://launchdarkly.com/docs/sdk/client-side/ios#initialize-the-client
let contextBuilder = LDContextBuilder(key: "EXAMPLE_CONTEXT_KEY")
guard case .success(let context) = contextBuilder.build() else {
print("LaunchDarkly: could not build context")
return
}
LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
if timedOut {
print("SDK didn't initialize in 5 seconds. SDK is still running and trying to get latest flags.")
} else {
print("SDK successfully initialized with the latest flags")
if let client = LDClient.get() {
// For onboarding only — events are flushed automatically in normal use.
client.flush()
}
}
}
print("SDK started.")
}Java (Server) — SDK detail
- Official docs: Java SDK reference
- API reference: Java server SDK API
- Published artifact: Maven Central
- Recipe (detect / install): SDK Recipes (Java Server)
Pin `version` to a current release from the SDK releases page. The blocks below mirror Install the SDK (Maven XML and Gradle); use the one that matches your build.
Maven (pom.xml):
<dependency>
<groupId>com.launchdarkly</groupId>
<artifactId>launchdarkly-java-server-sdk</artifactId>
<version>7.0.0</version>
</dependency>Gradle (Groovy) — long form as in the docs:
implementation group: 'com.launchdarkly', name: 'launchdarkly-java-server-sdk', version: '7.0.0'Gradle (Groovy) — common shortcut (still set a concrete or ranged version you intend to support):
implementation 'com.launchdarkly:launchdarkly-java-server-sdk:7.+'Gradle (Kotlin DSL) (build.gradle.kts):
implementation("com.launchdarkly:launchdarkly-java-server-sdk:7.+")OSGi “all” classifier (bundled Gson/SLF4J): see Using the Java SDK in OSGi.
Import (same topic):
import com.launchdarkly.sdk.*;
import com.launchdarkly.sdk.server.*;Initialize: `new LDClient(sdkKey)` connects with a default ~5s wait; use `isInitialized()` to see if startup succeeded. For custom timeouts and options, use `LDConfig.Builder`. `LDClient` must be a singleton per environment.
Includes: Minimal main sample. SDK key: `LAUNCHDARKLY_SDK_KEY` (Apply: environment configuration).
import com.launchdarkly.sdk.*;
import com.launchdarkly.sdk.server.*;
public class Main {
public static void main(String[] args) {
String sdkKey = System.getenv("LAUNCHDARKLY_SDK_KEY");
if (sdkKey == null || sdkKey.trim().isEmpty()) {
System.err.println(
"LAUNCHDARKLY_SDK_KEY is not set. Use Project settings > Environments > SDK key.");
System.exit(1);
}
try (LDClient client = new LDClient(sdkKey)) {
if (client.isInitialized()) {
// For onboarding only — events are normally flushed in the background.
client.flush();
System.out.println("LaunchDarkly client initialized.");
} else {
System.err.println(
"LaunchDarkly client did not initialize within the default wait; defaults apply until connected.");
System.exit(1);
}
}
}
}JavaScript (Browser) — SDK detail
- Official docs: JavaScript SDK reference
- API reference: Browser client (`@launchdarkly/js-client-sdk`)
- Recipe (detect / install): SDK Recipes (JavaScript Browser)
Use `@launchdarkly/js-client-sdk`: `createClient`, `start()`, then `waitForInitialization({ timeout })`. Always pass a timeout (the docs recommend 1–5 seconds); without one, connectivity issues can block your app. In v4, waitForInitialization always settles with a status (complete, failed, or timeout)—handle each path (Use promises to determine when the client is ready).
Client-side ID and env vars: Use the Client-side ID from Project settings > Environments (not a server SDK key). Bundler prefixes: Apply: environment configuration.
Use this in an ES module context that supports top-level await, or wrap in an async function.
Includes: Copy-paste onboarding sample below. After status === 'complete', replace the flush/log block with your own logic (the docs’ handleInitializedClient is only an illustration).
import { createClient } from '@launchdarkly/js-client-sdk';
const clientSideID = import.meta.env.VITE_LAUNCHDARKLY_CLIENT_SIDE_ID;
// A "context" is a data object representing users, devices, organizations, and
// other entities. You'll need this later, but you can ignore it for now.
const context = {
kind: 'user',
key: 'EXAMPLE_CONTEXT_KEY',
};
const client = createClient(clientSideID, context);
client.start();
const result = await client.waitForInitialization({ timeout: 5 });
if (result.status === 'complete') {
await client.flush();
console.log('SDK successfully initialized!');
} else if (result.status === 'failed') {
console.error('LaunchDarkly initialization failed:', result.error);
} else if (result.status === 'timeout') {
console.error(
'LaunchDarkly initialization timed out; the client keeps retrying in the background.',
);
}For Create React App, replace import.meta.env.VITE_LAUNCHDARKLY_CLIENT_SIDE_ID with process.env.REACT_APP_LAUNCHDARKLY_CLIENT_SIDE_ID. For Next.js, use process.env.NEXT_PUBLIC_LAUNCHDARKLY_CLIENT_SIDE_ID.
Lua (Server) — SDK detail
Primary: Lua SDK reference — LuaRocks, runtime integration (e.g. OpenResty, NGINX), initialization, and API.
Also useful:
- LuaRocks: launchdarkly modules
- GitHub: lua-server-sdk
- Samples: hello-lua-server, hello-haproxy, hello-nginx
- API docs: Lua SDK modules
Recipe (detect / install summary): SDK Recipes — Lua (Server)
There is no bundled onboarding code sample in this repo for Lua; follow the official reference.
Node.js (Client) — SDK detail
Primary: Node.js SDK reference (client-side) — npm install, initialization, and API.
Also useful:
- npm: launchdarkly-node-client-sdk
- GitHub: node-client-sdk
- Sample: hello-node-client
- API docs: Node.js client SDK API
Recipe (detect / install summary): SDK Recipes — Node.js (Client)
For Electron, use `electron-client-sdk.md` instead.
There is no bundled onboarding code sample in this repo for Node client; follow the official reference.
Node.js (Server) — SDK detail
- Official docs: Node.js SDK reference (server-side)
- API reference: SDK API docs
- Recipe (detect / install): SDK Recipes (Node.js Server)
Includes: Patterns below follow the Get started, Initialize the client, Evaluate a context, and Promises and async sections of the Node.js server-side SDK reference. Use one initialization strategy (waitForInitialization or the ready event—not both at once unless you know why). Aligns with Create First Feature Flag (evaluation uses context + default).
Singleton client
LDClient must be a singleton per LaunchDarkly environment—do not create a new client per request. Use your real SDK key from env vars, not a literal in source.
import { init } from '@launchdarkly/node-server-sdk';
const client = init(process.env.LAUNCHDARKLY_SDK_KEY);Wait for initialization (startup)
Run this once during process startup—for example before your HTTP server accepts connections, inside whatever async bootstrap your framework provides. The public docs use { timeout: 10 } (seconds); adjust as needed.
Promise style (from Promises and async):
client
.waitForInitialization({ timeout: 5 })
.then(() => {
// Initialization complete — safe to evaluate flags and/or start serving traffic.
})
.catch((err) => {
// Timeout or initialization failed
});Async/await (same topic—must live inside an async function your app already uses for startup):
try {
await client.waitForInitialization({ timeout: 5 });
// Initialization complete
} catch (err) {
// Timeout or initialization failed
}Alternative: the docs also document a ready event and callback-style client.variation(..., (err, value) => { ... }) under Evaluate a context—use that form if it fits your codebase better.
Evaluate a flag (when handling work)
The docs state that in production you should invoke variation as needed (not only once at import). Use await inside an async route handler, service method, job, etc.
const context = {
kind: 'user',
key: 'example-user-key',
name: 'Example User',
};
const showFeature = await client.variation('example-flag-key', context, false);For a boolean flag you may use boolVariation if you prefer; the official getting-started examples use variation with a boolean default.
PHP (Server) — SDK detail
Primary: PHP SDK reference — Composer, initialization, and API.
Also useful:
- Packagist: launchdarkly/server-sdk
- GitHub: php-server-sdk
- Sample: hello-php
- API docs: PHP SDK API
Recipe (detect / install summary): SDK Recipes — PHP (Server)
There is no bundled onboarding code sample in this repo for PHP; follow the official reference.
Python (Server) — SDK detail
- Official docs: Python SDK reference
- API reference: launchdarkly-server-sdk (Read the Docs)
- Published package: launchdarkly-server-sdk (PyPI)
- Recipe (detect / install): SDK Recipes (Python Server)
Use a current launchdarkly-server-sdk release; see the SDK releases page and version compatibility (Python 3.9+ from SDK 9.12+).
Install (Install the SDK):
pip install launchdarkly-server-sdkOptional observability (Python observability) — requires Python SDK 9.12+:
pip install launchdarkly-observabilityImport (same topic):
import ldclient
from ldclient.config import Config
# Optional — launchdarkly-observability package; requires Python SDK v9.12+
# from ldobserve import ObservabilityPluginInitialize: Call `ldclient.set_config(Config(...))` once, then `ldclient.get()` for the singleton client (Initialize the client). With observability: Config(sdk_key, plugins=[ObservabilityPlugin()]). Worker processes that fork may need `postfork()` (Considerations with worker-based servers).
Includes: Minimal onboarding script. SDK key: `LAUNCHDARKLY_SDK_KEY` (Apply: environment configuration).
import os
import sys
import ldclient
from ldclient.config import Config
if __name__ == "__main__":
sdk_key = os.environ.get("LAUNCHDARKLY_SDK_KEY")
if not sdk_key or not sdk_key.strip():
print(
"LAUNCHDARKLY_SDK_KEY is not set. Use Project settings > Environments > SDK key.",
file=sys.stderr,
)
raise SystemExit(1)
ldclient.set_config(Config(sdk_key))
client = ldclient.get()
if not client.is_initialized():
print("LaunchDarkly client failed to initialize", file=sys.stderr)
raise SystemExit(1)
# For onboarding only — events are normally flushed in the background.
client.flush()
print("LaunchDarkly client ready.")React Native — SDK detail
- Official docs: React Native SDK reference
- API reference: React Native SDK (`@launchdarkly/react-native-client-sdk`)
- Recipe (detect / install): SDK Recipes (React Native)
Current SDK: `@launchdarkly/react-native-client-sdk` v10 (TypeScript, Expo-compatible; iOS and Android only—not web). Build `ReactNativeLDClient` with the mobile key, wrap the app in `LDProvider`, and call `identify(context)` after mount (no context at construction). `identify` uses a 5s timeout by default; do not strip timeouts in custom configuration.
Install (non-Expo): Add `@react-native-async-storage/async-storage`, then run `npx pod-install` for iOS (Install the SDK).
Mobile key: Resolve a non-empty string at runtime (below uses Expo’s EXPO_PUBLIC_ env). Bare React Native typically uses react-native-config or native build settings—never hardcode keys in source. Logical name: Apply: environment configuration.
Includes: Copy-paste onboarding sample below.
import { useEffect } from 'react';
import {
AutoEnvAttributes,
LDProvider,
ReactNativeLDClient,
} from '@launchdarkly/react-native-client-sdk';
const mobileKey = process.env.EXPO_PUBLIC_LAUNCHDARKLY_MOBILE_KEY?.trim();
if (!mobileKey) {
throw new Error(
'LaunchDarkly: missing mobile key. For Expo, set EXPO_PUBLIC_LAUNCHDARKLY_MOBILE_KEY. For bare React Native, inject the key (for example react-native-config) and pass it here.',
);
}
const ldClient = new ReactNativeLDClient(mobileKey, AutoEnvAttributes.Enabled, {
debug: true,
applicationInfo: {
id: 'ld-rn-test-app',
version: '0.0.1',
},
});
// A "context" is a data object representing users, devices, organizations, and other entities.
const context = { kind: 'user', key: 'EXAMPLE_CONTEXT_KEY' };
const App = () => {
useEffect(() => {
ldClient.identify(context).catch((e: unknown) => {
console.error('LaunchDarkly identify failed:', e);
});
}, []);
return (
<LDProvider client={ldClient}>
<YourComponent />
</LDProvider>
);
};
export default App;Expo requires the `EXPO_PUBLIC_` prefix for process.env in app code; other setups should substitute their own resolved string for mobileKey.
React (Web) — SDK detail
- Official docs: React SDK reference · React Web SDK reference
- API reference: React Web SDK (`launchdarkly-react-client-sdk`)
- Recipe (detect / install): SDK Recipes (React Web)
Initialization: Prefer `asyncWithLDProvider` so the tree mounts after the underlying JavaScript client is ready (avoids startup flag flicker). Pass `timeout` in seconds (docs recommend 1–5); it is forwarded to waitForInitialization on the JS client (Configuration options). `withLDProvider` is an alternative if you accept initializing after the first mount.
Credentials: Client-side ID from Project settings > Environments (not a server SDK key). Bundler env prefixes: Apply: environment configuration.
Includes: Copy-paste sample for a Vite-style client entry (e.g. main.tsx). Requires React 16.8+ (asyncWithLDProvider uses hooks).
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { asyncWithLDProvider } from 'launchdarkly-react-client-sdk';
function App() {
return <div>Let your feature flags fly!</div>;
}
// A "context" is a data object representing users, devices, organizations, and other entities.
const context = {
kind: 'user',
key: 'EXAMPLE_CONTEXT_KEY',
email: 'user@example.com',
};
const clientSideID = import.meta.env.VITE_LAUNCHDARKLY_CLIENT_SIDE_ID?.trim();
if (!clientSideID) {
throw new Error(
'LaunchDarkly: missing client-side ID. Set VITE_LAUNCHDARKLY_CLIENT_SIDE_ID (Vite), REACT_APP_LAUNCHDARKLY_CLIENT_SIDE_ID (CRA), or NEXT_PUBLIC_LAUNCHDARKLY_CLIENT_SIDE_ID (Next.js client).',
);
}
void (async () => {
const LDProvider = await asyncWithLDProvider({
clientSideID,
context,
timeout: 5,
});
const rootEl = document.getElementById('root');
if (!rootEl) {
throw new Error('LaunchDarkly bootstrap: #root element not found');
}
createRoot(rootEl).render(
<StrictMode>
<LDProvider>
<App />
</LDProvider>
</StrictMode>,
);
})();For Create React App, read the ID from process.env.REACT_APP_LAUNCHDARKLY_CLIENT_SIDE_ID instead of import.meta.env.VITE_…. For Next.js client bundles, use process.env.NEXT_PUBLIC_LAUNCHDARKLY_CLIENT_SIDE_ID in a client entry ('use client' as required).
Roku (BrightScript) — SDK detail
Primary: Roku SDK reference — component install, initialization, and API.
Also useful:
- GitHub: roku-client-sdk (releases)
- Sample: hello-roku
Recipe (detect / install summary): SDK Recipes — Roku (BrightScript)
There is no bundled onboarding code sample in this repo for Roku; follow the official reference.
Ruby (Server) — SDK detail
Primary: Ruby SDK reference — Gemfile, initialization, and API.
Also useful:
- RubyGems: launchdarkly-server-sdk
- GitHub: ruby-server-sdk
- Samples: hello-ruby, hello-bootstrap-rails
- API docs: Ruby SDK API
Recipe (detect / install summary): SDK Recipes — Ruby (Server)
There is no bundled onboarding code sample in this repo for Ruby; follow the official reference.
Rust (Server) — SDK detail
Primary: Rust SDK reference — crates.io, initialization, and API.
Also useful:
- crates.io: launchdarkly-server-sdk
- GitHub: rust-server-sdk
- Sample: hello-rust
- API docs: docs.rs launchdarkly-server-sdk
Recipe (detect / install summary): SDK Recipes — Rust (Server)
There is no bundled onboarding code sample in this repo for Rust; follow the official reference.
Vue — SDK detail
Primary: Vue SDK reference — npm install, plugin setup, and API.
Also useful:
- npm: launchdarkly-vue-client-sdk
- GitHub: vue-client-sdk
- API docs: Vue SDK API
Recipe (detect / install summary): SDK Recipes — Vue
There is no bundled onboarding code sample in this repo for Vue; follow the official reference.