Skip to content

Latest commit

 

History

History
196 lines (147 loc) · 4.44 KB

File metadata and controls

196 lines (147 loc) · 4.44 KB

DevCycle

OpenFeature-native feature flag management platform for controlled releases, A/B testing, and experimentation.

GitHub Education Access

Claim your free access at GitHub Education Pack - look for DevCycle.

Dashboard

Features

  • Feature Flags: Toggle features without deployment
  • Gradual Rollouts: Release to percentage of users
  • A/B Testing: Experiment with variations
  • Targeting: Rules based on user properties
  • OpenFeature Native: No vendor lock-in
  • 15+ SDKs: Web, mobile, backend

Quick Setup

JavaScript/Node.js

npm install @devcycle/nodejs-server-sdk
import { initializeDevCycle } from '@devcycle/nodejs-server-sdk';

const devcycleClient = await initializeDevCycle(
  process.env.DEVCYCLE_SERVER_SDK_KEY
);

const user = { user_id: 'user-123' };
const showNewFeature = await devcycleClient.variableValue(
  user,
  'new-feature-flag',
  false
);

if (showNewFeature) {
  // Show new feature
}

React

npm install @devcycle/react-client-sdk
import { DevCycleProvider, useVariableValue } from '@devcycle/react-client-sdk';

function App() {
  return (
    <DevCycleProvider
      sdkKey={process.env.REACT_APP_DEVCYCLE_CLIENT_SDK_KEY}
      user={{ user_id: 'user-123' }}
    >
      <MyComponent />
    </DevCycleProvider>
  );
}

function MyComponent() {
  const showFeature = useVariableValue('new-feature', false);
  return showFeature ? <NewFeature /> : <OldFeature />;
}

Python

pip install devcycle-python-server-sdk
from devcycle_python_sdk import DevCycleLocalClient, DevCycleLocalOptions

options = DevCycleLocalOptions()
client = DevCycleLocalClient(os.environ.get("DEVCYCLE_SERVER_SDK_KEY"), options)

user = {"user_id": "user-123"}
show_feature = client.variable_value(user, "new-feature", False)

Configuration

Copy from templates/devcycle/:

  • devcycle.config.js - SDK configuration
  • .env.example - Environment variables

Environment Variables

DEVCYCLE_SERVER_SDK_KEY=server-key-here
# Get from: https://app.devcycle.com → Project → Environments → Server SDK Key

DEVCYCLE_CLIENT_SDK_KEY=client-key-here
# Get from: https://app.devcycle.com → Project → Environments → Client SDK Key

Feature Flag Types

Boolean Flag

const enabled = await client.variableValue(user, 'feature-enabled', false);

String Variation

const theme = await client.variableValue(user, 'ui-theme', 'light');
// Returns: 'light', 'dark', 'auto'

JSON Configuration

const config = await client.variableValue(user, 'feature-config', {});
// Returns: { maxItems: 10, showBanner: true }

Targeting Rules

By User Property

const user = {
  user_id: 'user-123',
  email: 'user@example.com',
  customData: {
    plan: 'premium',
    country: 'US'
  }
};
// Target users where plan = 'premium'

Percentage Rollout

  • 10% → Test with small group
  • 50% → Broader beta
  • 100% → Full release

GitHub Actions Integration

# .github/workflows/devcycle-sync.yml
name: DevCycle Sync

on:
  push:
    branches: [main]

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: DevCycle Code References
        uses: DevCycleHQ/feature-flag-code-refs@v1
        with:
          client-id: ${{ secrets.DEVCYCLE_CLIENT_ID }}
          client-secret: ${{ secrets.DEVCYCLE_CLIENT_SECRET }}
          project: your-project-key

Best Practices

  1. Use descriptive names: show-new-checkout not flag-1
  2. Set defaults: Always provide fallback values
  3. Clean up old flags: Remove after full rollout
  4. Test variations: Verify all flag states work
  5. Use targeting: Roll out to internal users first

OpenFeature Integration

import { OpenFeature } from '@openfeature/js-sdk';
import { DevCycleProvider } from '@devcycle/openfeature-web-provider';

OpenFeature.setProvider(new DevCycleProvider(sdkKey));
const client = OpenFeature.getClient();

const showFeature = await client.getBooleanValue('new-feature', false);

Resources