# Migrate  FROM

## LaunchDarkly

Switch from LaunchDarkly to Reflag in _a single day_

Kick-start your migration from LaunchDarkly to Reflag with a few simple steps. For most, the migration can be completed in a single day.

### **Run import tool**

Start by importing flags and segments. You’ll need your LaunchDarkly project ID and an API token.

[Open import tool](https://app.reflag.com/env-current/settings/app-import)

### **Prompt your agent**

Use our pre-built prompt switch your code over.

[Copy prompt](https://reflag.com/migrate/launchdarkly#)

### Package Mappings
- `launchdarkly-react-client-sdk` ↔ `@reflag/react-sdk`
- `launchdarkly-vue-client-sdk` ↔ `@reflag/vue-sdk`
- `launchdarkly-node-server-sdk` ↔ `@reflag/node-sdk`
- `@launchdarkly/node-server-sdk` ↔ `@reflag/node-sdk`

### Key Mappings
- `clientSideID` ↔ `publishableKey`
- `serverSideID` ↔ `secretKey`
- `REACT_APP_LD_CLIENT_SIDE_ID` ↔ `REACT_APP_REFLAG_PUBLISHABLE_KEY`
- `LAUNCHDARKLY_SDK_KEY` ↔ `REFLAG_SECRET_KEY`

### Context Format
LaunchDarkly: 
```
{kind: 'user', key: 'john-doe-1'}
```
Reflag:
```
{
  user: {id: 'john-doe-1', name: 'John Doe', email: 'john@acme.com', avatar: 'https://...'},
  company: {id: 'acme-inc-1', name: 'Acme, Inc', plan: 'pro', avatar: 'https://...'}
}
```
Type: `LDContext` → `ReflagContext`

### React

**Before:**
```
import {asyncWithLDProvider} from 'launchdarkly-react-client-sdk';
const LDProvider = await asyncWithLDProvider({clientSideID: 'xxx', context});
<LDProvider><App/></LDProvider>
```

**After:**
```
import {ReflagProvider} from "@reflag/react-sdk";
<ReflagProvider 
  publishableKey="xxx" 
  context={{user:{id:"1"},company:{id:"2"}}} 
  loadingComponent={<Loading/>} // optional: shown while flags load
>
  {/* children render when loading finishes, or immediately if no loadingComponent */}
  <App/>
</ReflagProvider>
```

**Flag usage - IMPORTANT: useFlags() becomes multiple useFlag() calls:**
```
// Before: const {devTestFlag, anotherFlag} = useFlags();
// After:
import {useFlag} from '@reflag/react-sdk';
const {isEnabled: devTestFlag} = useFlag('dev-test-flag');
const {isEnabled: anotherFlag} = useFlag('another-flag');
```

Notes:
- `useFlags` → multiple `useFlag` calls (one per flag)
- `withLDConsumer` → no direct equivalent; call `useFlag` inside the component instead
- `useLDClient` → `useClient`
- `useLDClientError` → no equivalent
- `LDProvider` → `ReflagProvider`
- `deferInitialization` not needed (always deferred)
- use `<ReflagBootstrappedProvider>` for bootstrapping flags for SSR or similar. See `getFlagsForBootstrap` in the Node SDK.

### Vue

**Before (plugin pattern):**
```
import {LDPlugin} from 'launchdarkly-vue-client-sdk'
app.use(LDPlugin, {clientSideID: 'xxx', deferInitialization: true})
app.mount('#app')
```

**After (provider component pattern):**
```
<script setup>
import {ReflagProvider} from "@reflag/vue-sdk";
</script>
<template>
  <ReflagProvider :publishable-key="key" :context="{user:{id:'1'}}">
    <App/>
  </ReflagProvider>
</template>
```

**Flag usage:**
```
// Before: const flag = useLDFlag('key', false)
// After:
import {useFlag} from "@reflag/vue-sdk";
const {isEnabled} = useFlag('key')  // fallback is always false
```

Notes:
- `LDPlugin` → `ReflagProvider` (plugin pattern → component pattern)
- `useLDFlag` → `useFlag`
- `deferInitialization` not needed (always deferred)
- similar to the React SDK, use `<ReflagBootstrappedProvider>` for bootstrapping flags

### Node

**Before:**
```
import {init} from '@launchdarkly/node-server-sdk';
const client = init(sdkKey);

const context = {kind: 'user', key: 'example-user-key', name: 'Sandy'};

await client.waitForInitialization();
console.log("LaunchDarkly initialized!");
const val = await client.variation('flag', context, false);
```

**After:**
```
import {ReflagClient, ReflagContext} from "@reflag/node-sdk";
const client = new ReflagClient({secretKey});

const context: ReflagContext = {
  user: {id: "john_doe", name: "John Doe", email: "john@acme.com", avatar: "https://..."},
  company: {id: "acme_inc", name: "Acme, Inc.", plan: "pro", avatar: "https://..."}
};

await client.initialize();
console.log("Reflag initialized!");
const {isEnabled} = client.getFlag({key:'flag', ...context}); // returns {isEnabled: boolean}
```

**Test overrides:**
```
// Before (LD):
const td = new TestData();
testData.update(td.flag('flag-key').booleanFlag().variationForAll(true));
const client = new LDClient('KEY', {updateProcessor: td.getFactory()});

// After (Reflag):
client.flagOverrides = {'flag-key': true};
```

**Bootstrapping:**

Use `const bootstrappedFlags = client.getFlagsForBootstrap(context);` on the server side to get a flags package ready for passing to the client/browser SDKs.

### Testing
Run tests and lint fixes after migration to verify everything works.

### Docs
READMEs (source of truth):
- React: https://raw.githubusercontent.com/reflagcom/javascript/refs/heads/main/packages/react-sdk/README.md
- Vue: https://raw.githubusercontent.com/reflagcom/javascript/refs/heads/main/packages/vue-sdk/README.md
- Node: https://raw.githubusercontent.com/reflagcom/javascript/refs/heads/main/packages/node-sdk/README.md

Reference docs:
- React: https://docs.reflag.com/supported-languages/react-sdk/globals.md
- Vue: https://docs.reflag.com/supported-languages/vue-sdk/globals.md
- Node: https://docs.reflag.com/supported-languages/node-sdk/globals.md

### **Free until renewal**

For enterprise plans, we won't charge you for Reflag until your LaunchDarkly renewal. E-mail us take to [take advantage](mailto:hello@reflag.com?subject=Free%20until%20renewal)

Problems migrating? [We’re here to help](mailto:hello@reflag.com?subject=LaunchDarkly%20migration)
