BlogRight arrowDeveloper Productivity
Right arrow5 best practices for getting started with LaunchDarkly
Backspace icon
Search iconClose icon

MAR 12 2025

5 best practices for getting started with LaunchDarkly

Set up your first project, choose an SDK, and start using feature flags.

5 best practices for getting started with LaunchDarkly featured image

Sign up for our newsletter

Get tips and best practices on feature management, developing great AI apps, running smart experiments, and more.

Subscribe
Subscribe

When implementing or adopting a new technology, there always comes a time when we shift out of the research phase and set the wheels of change in motion. You know the what and the why of your new solution, but now comes the hardest part: the how

Feature management is no different. You've done the research, reading articles like The Five Stages of Feature Flag Adoption or Why Decouple Deployments from Releases and know that LaunchDarkly is the right tool for your organization. But how do you get started? Here’s we’re providing five next steps for getting off the ground with LaunchDarkly.

1. Set up your project

If you haven’t done so already, sign up for a LaunchDarkly account. If you’re not a customer, you can create a Developer account that’s free forever and includes 14 days of unlimited access to all of LaunchDarkly's capabilities. Once you have an account, you can start using LaunchDarkly right away.

Get started

After you log in you will be presented with an onboarding screen. Choose the option that best fits your needs or try multiple options, one at a time. 

  • Quickstart guide allows you to follow a step-by-step workflow to create your first flag, install SDK, and enable your first feature. 
  • Explore the sandbox allows you to play around the LaunchDarkly UI and experience features for yourself. 
  • CLI walks you through the steps for interfacing with Launchdarkly using your terminal.
  • Import flags allows you to import flags from your Split and Unleash implementations.

Projects

LaunchDarkly is set up around projects. A LaunchDarkly organization contains all of that organization’s projects, which are composed of LaunchDarkly environments.

When to use large, consolidated projects

If your engineering team has shared technologies, resources, or a common production path, you should opt for a single large project. This allows better organization enabling clean separations for SDKs, role access, and UX.

When to use separate projects

You should only use separate projects when product areas are completely independent, with no shared resources or dependencies. A key indicator is a distinct path to production. Since projects act as strict boundaries, backtracking after separation can be challenging.

We automatically provide you with a project called “Default Project” which you can use — or you can create a new one. To do this, go to the Account Settings tab within LaunchDarkly, select Projects, and then select Create Project:

Example of how to create a project

Environments

If a project represents your applications as a whole, an environment represent the release stages of that application. 

Think about the series of stages that your software releases typically go through: development, QA, testing, staging, production, etc. LaunchDarkly environments allow you to replicate your software release stages so you can manage releases through the entire lifecycle. 

Projects can contain multiple environments, and each environment uses different server-side, client-side, and mobile SDK keys. As flags are changed to serve different variations, those variations only get served to applications connected to LaunchDarkly with the specified environment keys.

Here's an example of multiple environments within a LaunchDarkly project:

Example of multiple environments within a LaunchDarkly project

It’s important to keep track of where various features are in the release lifecycle. LaunchDarkly release assistant lets you create an aggregated view of your environments and monitor the status of each feature as it moves from stage to state. Having this type of insight can be especially important as you start to add more users to your projects.

Here's an example of a release pipeline in LaunchDarkly:

example of a release pipeline in LaunchDarkly

2. Choose your SDK

Now that we have our projects and environments ready to go, it’s time to connect our application to LaunchDarkly. LaunchDarkly supports over 25 different SDKs, meaning we can support whatever language you are programming in. Let’s walk through the steps for initializing a LaunchDarkly SDK.

Get your SDK keys

As mentioned earlier, each LaunchDarkly environment has its own unique set of SDK keys. Let’s quickly walk through the different keys and how they are used:

  • Server-side: Backend, multi-user systems, like web servers. Intended for secure environments.
  • Client-side: Designed for single users (e.g. mobile devices, browser sessions, etc.) and edge use cases. Not expected to be used in as secure an environment as server-side SDKs. 
  • Mobile SDK key: Similar to client-side, but also includes multi-environment support and handles the polling/streaming connection with LaunchDarkly slightly differently. 
  • AI SDK key: While LaunchDarkly server-side, client-side, and edge SDKs focus on interacting with feature flags, the LaunchDarkly AI SDKs interact with AI configs. AI configs are resources that you create in LaunchDarkly and use to customize, test, and roll out new large language models (LLMs) within your generative AI applications.

It’s important to choose the correct key for the SDK that you intend to use. Typically, problems with initializing the SDK or connecting to LaunchDarkly can be traced back to the wrong SDK key being used. To get these values you can choose one of two paths: 

  1. Retrieve from Account Settings. As we showed above, the SDK keys are available in the Projects screen. Go to that tab, select the project and environment that you want the keys for. 
  2. On the Flags dashboard click on the More Actions menu for the environment and copy the SDK key.

null

null

Once you have the correct key values, you’re ready to initialize your SDK.

Installing and initializing LaunchDarkly SDK

Each LaunchDarkly SDK follows the same pattern for initializing an SDK. First, you import/install the required SDK package into your application environment and then you configure it within your application using the SDK keys you retrieved. We’re doing two primary things when we initialize the SDK. First we import the SDK that we just installed then we run an initialization command to connect to LaunchDarkly. 

Here are a couple of examples using some of our most popular frameworks:

Javascript SDK

Step 1: Installation 
Install the SDK using a package manager, like npm, yarn, or bower:

npm install lauchdarkly-js-client-sdk

Step 2: Set up client initialization, which will look something like this:

import * as LaunchDarkly from "launchdarkly-js-client-sdk"

const context = {
	kind: "user",
	key: "context-key-123abc",
	name: "anonymous"
};

const client = LaunchDarkly.initialize("<add your client-side key as an env variable>", context);
Python SDK

Step 1: Install the correct SDK package:
Install the SDK using a package manager, like pip:

pip install launchdarkly-server-sdk

Step 2: Set up client initialization, which will look something like this:

import os
import ldclient
from ldclient.config import Config

# Set sdk_key to your LaunchDarkly SDK key before running
sdk_key = os.getenv("LAUNCHDARKLY_SERVER_KEY")

if __name__ == "__main__":
	if not sdk_key:
    	show_message("Please set the LAUNCHDARKLY_SERVER_KEY env first")
    	exit()

	ldclient.set_config(Config(sdk_key))

	# The SDK starts up the first time ldclient.get() is called
	if ldclient.get().is_initialized():
    	show_message("SDK successfully initialized!")
	else:
    	show_message("SDK failed to initialize")
        exit()

	# Set up the evaluation context. This context should appear on your
	# LaunchDarkly contexts dashboard soon after you run the demo.
	context = Context.builder('example-user-key').name('Sandy').build()
React Web SDK (Typescript on Next.js)

Quick note: this is showing the configuration of a Next.js React project. Because Next assumes that all components should be rendered server side, there are some additional configurations required. 

We need to make sure that LaunchDarkly is treated as a client-side component in order to receive and process real time updates. React has a number of different configurations, so be sure to read the SDK documentation for your specific setup

Step 1: Install the correct SDK package:
Install the SDK using a package manager, like npm, yarn, or bower:

npm install launchdark-react-client-sdk

Step 2: Initialize the SDK in a React component

//component file, named like LDProvider.tsx 
"use client";

import { use } from "react";
import { asyncWithLDProvider } from "launchdarkly-react-client-sdk";

export default function AsyncLDProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const LDDynaProvider = use(
	asyncWithLDProvider({
  	clientSideID: process.env.NEXT_PUBLIC_LD_CLIENT_SDK_KEY || '',
  	reactOptions: {
    	useCamelCaseFlagKeys: false
  	},
  	context: {
    	kind: "user",
    	key: "1",
    	name: "Anonymous",
  	},
	})
  );

  return <LDDynaProvider>{children}</LDDynaProvider>;
}

Step 3: Wrap your application with the Provider component

//in your layout.tsx file
import dynamic from "next/dynamic";
import { Suspense } from "react";

const AsyncLDProvider = dynamic(() => import("@/components/ldprovider"), {
  ssr: false,
});

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
	<html lang="en">
  	<body className={inter.className}>
    	<Suspense fallback={<div>Loading...</div>}>
      	<AsyncLDProvider>{children}</AsyncLDProvider>
    	</Suspense>
  	</body>
	</html>
  );
}
iOS SDK

Step 1: Install the SDK with Swift Package Manager, CacaoPods, Carthage, and add it to the coordinating configuration file. Here’s the example using Package.swift:

//place in your Package.swift file 
   dependencies: [
       .package(url: "https://github.com/launchdarkly/ios-client-sdk.git", .upToNextMinor("9.0.0")),
   ],
   targets: [
       .target(
           name: "YOUR_TARGET",
           dependencies: ["LaunchDarkly"]
       )
   ],
//... 

Step 2: Initialize the SDK in your application.

let config = LDConfig(mobileKey: "mobile-key-123abc", autoEnvAttributes: .enabled)
let context  = LDContextBuilder(key: "context-key-123abc")
context.trySetValue("name", .string("Sandy"))
context.trySetValue("email", .string("sandy@example.com"))

LDClient.start(config: config, context: context, startWaitSeconds: 5) { timedOut in
	if timedOut {
    	// Client may not have the most recent flags for the configured context
	} else {
    	// Client has received flags for the configured context
	}
}

These are just a handful of examples of how you can initialize a LaunchDarkly SDK, but they all follow the same core structure. Install the SDK package into your application environment, initialize the SDK to establish a connection, start using LaunchDarkly within the app.

Once the SDK has been initialized, you’ll be able to evaluate flag values, send custom events from the app to LaunchDarkly, identify and update custom contexts, and so much more. For more information about initializing a specific SDK, visit the SDK documentation.

3. Create your first flag

Now that you’ve set up your project and enabled your application to communicate with LaunchDarkly, you’re ready to start feature flagging! As mentioned in our Five Stages of Feature Flag Adoption article, most organizations will start with boolean flags – determining which code is served to a user based on a true or false value.

Starting with boolean flags is foundational to understanding the power of a feature management platform not only because it provides immediate value, but it’s also the least intrusive on your development workflow. For example, here’s what a boolean flag evaluation looks like on a Node.js server for evaluating different API routes:

// initializing the client
const client = ld.init(process.env.SDK_KEY, context);

app.get('/api', async (req, res) => {
  // evaluate the flag and store value in a variable, in this case called newRoute 
  const newRoute = await client.variation('new-route-flag-key', false);
  
  //run an if/else statement based on value of newRoute
  if (newRoute) {
    try {
      //new API route logic
    } catch (e) {
      console.error(error.message);
    }
  } else {
    try {
      //old API route logic 
    } catch (e) {
      console.error(error.message);
    }
  }
});

If you’ve used if/else logic in your code before, then you’re ready to start writing feature flags into your code. But with LaunchDarkly there is so much more that can be done beyond the boolean flag. LaunchDarkly supports multiple variation types including boolean, strings, numbers, and JSON objects. Using non-boolean flags enables the user to create multivariate flags.

Multivariate flags can serve more than two variations and are great for passing in dynamic values or running experiments. Here’s an example code block where we are using a multivariate flag to determine which image gallery to display based on the user’s region in a React application:

// In react we use a useFlags() hook instead of the .variation function, 
// it's unique to React, but functionally serves the same purpose, 
// we're just using the hook to evaluate the flag key region 
const {region} = useFlags();

// Depending on the value returned from region, we render didn't image galleries. 
// code for mountain west 
if (region == "mountainWest") {
  return (
    <Box sx={{ width: 900, height: 300, overflowY: 'scroll' }}>
      <ImageList variant="masonry" cols={5} gap={8}>
        {mountainWest.map((item) => (
          <ImageListItem key={item.img}>
            <img
              src={`${item.img}?w=248&fit=crop&auto=format`}
              srcSet={`${item.img}?w=248&fit=crop&auto=format&dpr=2 2x`}
              alt={item.title}
              loading="lazy"
            />
          </ImageListItem>
        ))}
      </ImageList>
    </Box>
  );
}

//code for pacific northwest
if (region == "pacificNorthwest") {
  return (
    <Box sx={{ width: 900, height: 300, overflowY: 'scroll' }}>
      <ImageList variant="masonry" cols={5} gap={8}>
        {pacificNorthwest.map((item) => (
          <ImageListItem key={item.img}>
            <img
              src={`${item.img}?w=248&fit=crop&auto=format`}
              srcSet={`${item.img}?w=248&fit=crop&auto=format&dpr=2 2x`}
              alt={item.title}
              loading="lazy"
            />
          </ImageListItem>
        ))}
      </ImageList>
    </Box>
  );
}

// code for the west coast
if (region == "westCoast") {
  return (
    <Box sx={{ width: 900, height: 300, overflowY: 'scroll' }}>
      <ImageList variant="masonry" cols={5} gap={8}>
        {westCoast.map((item) => (
          <ImageListItem key={item.img}>
            <img
              src={`${item.img}?w=248&fit=crop&auto=format`}
              srcSet={`${item.img}?w=248&fit=crop&auto=format&dpr=2 2x`}
              alt={item.title}
              loading="lazy"
            />
          </ImageListItem>
        ))}
      </ImageList>
    </Box>
  );
}

The code block is a little lengthy, but essentially we’re just rendering different image galleries based on the string value returned from our region flag. 

4. Expand flag usage

Now that you’ve gotten your first feature flagged with a boolean flag or multivariate flag, you’re ready to start expanding your use cases with feature flags. The process of implementing them in code is going to be the same, but the purpose behind the flag can be very different. Fortunately, LaunchDarkly knows this and tries to provide you with some guidance for how different flags should be used. We call these "flag templates." 

Flag templates are predefined configurations for various uses of LaunchDarkly feature flags. The default templates include:

  • Release flags: temporary flags used for releasing new features. This template defaults to a boolean and automatically switches the default rule to serve the “off” variation. 
  • Kill switch flags: permanent flags used for managing application wide functionality, ex: maintenance modes or third-party integrations. This template also defaults to a boolean, but does not change the default rule. 
  • Experiment flags: temporary flag used for running LaunchDarkly experiments against new features. Defaults to a string flag with three variations: control, variation A, and variation B. 
  • Migration flags: A unique temporary flag that is used for managing database migrations with LaunchDarkly. Offers two, four, and six stage migrations paths. For a deeper dive, read this migration article
  • Custom flag templates: None of these other templates seem to be exactly right? Customize your own flag template and save it for future use! 

Each of these templates has a default starting point, but they are all customizable and can be saved. If there’s a specific pattern without your application that you want to enforce, then using custom templates is probably the best option for your organization.

5. Set up access controls

Let’s recap. We’ve set up our project, selected our SDKs, implemented our first feature flags, and started to expand how we use feature flags in our application.

At this point, you’re probably ready to let the rest of the team have access to your project. This leads us to our final best practice: setting up access controls for your LaunchDarkly project.

LaunchDarkly is a collaborative tool, but you still want to make sure you’re enforcing the right permissions and ensuring that only the right users are accessing the right environments/flags. Fortunately, LaunchDarkly is designed for teams of all sizes and offers granular access controls.

User roles

By default, LaunchDarkly supports four different types of user roles: 

  • Owner: The one who created the LaunchDarkly organization or has been delegated the ownership role by a previous owner. This user has complete control over the entire LaunchDarkly organization including projects, environments, billing, etc. There is only one per organization. 
  • Administrators: Similar to owners in that they can do just about anything, except for changing whoever has the owner role. You can have multiple administrators in an account.  
  • Writers: Can create and modify LaunchDarkly flags, projects, and environments, but has no control over administrative tasks like billing or managing account members.  
  • Readers: Can view any information, but cannot make changes. Good for users that need to access LaunchDarkly for information, but do not need the ability to change things. 

Any member that is added to a LaunchDarkly organization is assigned one of these roles. However, you are not limited to only these four. LaunchDarkly also supports the ability to create custom roles which give you the ability to make a user's capabilities as broad or as narrow as is required. Custom roles can be applied to specific individuals or across entire teams.

Teams

LaunchDarkly teams are how you group together users and manage their access across projects, environments, and even individual flags. You can use teams to organize end users and apply team-wide custom roles that can be as broad or as granular as you want. For example, say you want to give a team access to flags within a given project, but restrict their ability to manage your user segments. This could be because you’re using a third party tool for importing segment data or maybe you want a specific user managing those end user groups. Regardless the reason, you can apply a team wide policy that restricts access to all segments like this:

Organizational settings in LaunchDarkly

A custom role that allows access to feature flags, but not segments in the toggle-store project

In this policy, team members would be able to create, change, and delete flags, but could not do anything with the segments in that project. These roles can be applied to individual flags or individual actions as well.

Next up: explore more use cases

We’ve only scratched the surface of what you can do with LaunchDarkly. LaunchDarkly targeting lets you control the impact radius of your releases and create personalized experiences for your users based on things like entitlements. Create guarded rollouts to de-risk your releases. AI Configs allow you to iterate on models and prompts in runtime. LaunchDarkly Experimentation helps you validate the efficacy of your releases by measuring their impacts based on business metrics.

LaunchDarkly even integrates with 60+ tools ranging from application performance monitoring (APM) tools, CI/CD platforms and collaboration tools. Now that you’re up and running with your own LaunchDarkly project, you can pick and choose which one of these use cases to explore next.

Like what you read?
Get a demo
Previous
Next