Thank you for your interest in contributing to the LaunchDarkly Toolbar! This guide will help you get set up and understand our development workflow.
- Development Setup
- Toolbar Integration Modes
- Development Workflow
- Running the Project
- Testing
- Building
- Publishing
- Code Standards
- Pull Request Process
- Node.js 18+ and pnpm 10+
- Fork and clone the repository:
git clone https://github.com/your-username/launchdarkly-toolbar.git
cd launchdarkly-toolbar- Install dependencies:
pnpm install- Run development servers :
pnpm dev:cdn
pnpm dev:server # Serve compiled toolbar code on a localhost port (defaults to port 5764)- Verify everything works:
pnpm build
pnpm test
pnpm demo # Run the standalone demo application to test toolbar code in an example applicationThis repository contains a Demo React application that is configured to use the LaunchDarkly Developer Toolbar to provide
an easy and intuitive way to test local changes to the Developer Toolbar within the context of a simple example web
application. To set up the Demo application + Developer Toolbar to use one of your LaunchDarkly projects, copy
the values in .env.example into a .env (or .env.local) file, and replace VITE_LD_CLIENT_SIDE_ID with the
LaunchDarkly Client-Side ID of the project/environment you would like to test against.
The other values in env.example are most likely fine as-is. If you are planning on developing features for/testing using
a local dev-server, ensure you also update VITE_LD_DEV_SERVER_URL and VITE_LD_DEV_SERVER_URL_PROJECT_KEY to valid values.
The toolbar package has its own internal LaunchDarkly client for toolbar feature flags and analytics. This is separate from the demo application configuration:
- Navigate to the toolbar package directory:
packages/toolbar/ - Copy the values from
.env.exampleinto a new.env(or.env.local) file in that same directory - Configure the following environment variables:
TOOLBAR_INTERNAL_CLIENT_ID- Your LaunchDarkly Client-Side ID for toolbar features (required)TOOLBAR_INTERNAL_BASE_URL- LaunchDarkly base URL (defaults tohttps://app.launchdarkly.com)TOOLBAR_INTERNAL_STREAM_URL- LaunchDarkly stream URL (defaults tohttps://clientstream.launchdarkly.com)TOOLBAR_INTERNAL_EVENTS_URL- LaunchDarkly events URL (defaults tohttps://events.launchdarkly.com)TOOLBAR_INTERNAL_BACKEND_URL- Backend URL for Observability and Session Replay (defaults tohttps://pub.observability.launchdarkly.com)TOOLBAR_INTERNAL_OBSERVABILITY_OTLP_ENDPOINT- OTLP HTTP endpoint for Observability tracing (OpenTelemetry)
Note: This configuration is optional and only needed if you're developing or testing toolbar-specific feature flags. If not provided, the toolbar's internal client will not be initialized, and the toolbar will function normally without it. The URL configurations are only needed if you're using a custom LaunchDarkly instance.
The LaunchDarkly Toolbar supports two integration modes:
- SDK Mode (recommended): Integrates directly with your LaunchDarkly React SDK for local flag overrides and testing
- Dev Server Mode: Connects to a LaunchDarkly CLI dev server for flag browsing and real-time updates
For Dev Server Mode setup instructions, see DEV_SERVER_SETUP.md.
To allow for contributors to easily test toolbar changes locally, this repository comes with a standalone Demo application, as well as a local "dev server" that will host the locally compiled toolbar code on a localhost port (defaults to 5764). The Demo application is a react application and allows contributors to easily test the toolbar in both SDK Mode and Dev Server Mode.
To set up the Demo application, copy the values in .env.example into a .env.local file and replace them where applicable.
More than likely, the only environment variable you will need to fill in will be VITE_LD_CLIENT_SIDE_ID with your
corresponding Client-Side ID for the project/environment you want to instantiate the LaunchDarkly client and the
Developer Toolbar with.
This project uses pnpm workspaces to manage packages in a monorepo structure:
- Root - Monorepo orchestrator (private, never published)
- packages/toolbar/ - The main toolbar library package (published to npm)
- packages/demo/ - Demo application for testing and development
| Command | Description |
|---|---|
pnpm build |
Build the toolbar library for production |
pnpm demo |
Build toolbar and run the demo application |
pnpm demo:mock |
Run demo application with mock flags enabled |
pnpm demo:build |
Build both toolbar and demo for production |
pnpm demo:build:mock |
Build demo for production with mock flags enabled |
pnpm dev |
Build toolbar in watch mode for development |
pnpm dev:link |
Link local SDKs and set pnpm overrides (advanced) |
pnpm dev:status |
Check health of repos, links, ports, tools (advanced) |
pnpm dev:unlink |
Restore registry versions when done (advanced) |
pnpm dev:watch |
Start watch + demo (advanced) |
pnpm format |
Format code with Prettier |
pnpm format:ci |
Check code formatting in CI |
pnpm lint |
Run linter across all packages |
pnpm storybook |
Run Storybook for component development |
pnpm build:storybook |
Build Storybook for production |
pnpm test |
Run unit tests for toolbar |
pnpm test:e2e:ci |
Run E2E tests against the packaged version |
pnpm test:e2e:ci:ui |
Run E2E tests with Playwright UI against the packaged version |
pnpm test:e2e:local |
Run E2E tests against the local version |
pnpm test:e2e:local:ui |
Run E2E tests with Playwright UI against the local version |
- Start the build in watch mode:
pnpm dev- In a separate terminal, run the demo:
pnpm demo- Open your browser to
http://localhost:5173
pnpm storybookOpen http://localhost:6006 to view and develop components in isolation.
For development without a real LaunchDarkly connection:
# Run demo with mock flags
pnpm demo:mock
# Build demo with mock flags for production
pnpm demo:build:mockThis is useful when you want to test the toolbar functionality without setting up a LaunchDarkly environment or dev server.
Use this only when developing the toolbar alongside local SDK changes (js-sdk-common and js-client-sdk). For normal toolbar work, prefer the demo app directly.
When to use:
- You are editing
js-sdk-commonand/orjs-client-sdkand want live updates in the demo.
Commands:
# 1) Link local SDKs and set pnpm overrides in this repo
pnpm dev:link
# 2) Check health (repos, links, ports, tools)
pnpm dev:status
# 3) Start watch + demo
pnpm dev:watch
# 4) Restore registry versions when done
pnpm dev:unlinkConfiguration (optional):
- Flags:
--js-common <dir>,--js-client <dir>,-w|--workspace <dir> - Env vars:
LD_JS_COMMON_DIR,LD_JS_CLIENT_DIR,LD_WORKSPACE_DIR - Precedence: flags > env > defaults
The demo application is the best way to test your changes:
- Make changes to the source code
- The build watch mode will automatically rebuild
- Refresh the demo page to see your changes
- Use the demo's configuration panel to test different scenarios
- Test both SDK Mode and Dev Server Mode to ensure compatibility
Testing Both Modes:
- SDK Mode: Test flag overrides, event interception, and real-time updates
- Dev Server Mode: Test dev server connection, flag browsing + overrides (via the dev server), and CLI integration
We use Vitest for unit testing:
# Run tests once
pnpm test
# Run tests in watch mode
pnpm test --watch
# Run tests with coverage
pnpm test --coverageTest files location: src/tests/ or adjacent to components (*.test.tsx)
We use Playwright for E2E testing with different environments and integration modes:
Test Environments:
- CI environment (
test:e2e:ci): Uses the packaged version. Runpnpm buildfirst to ensure you have the latest changes - Local environment (
test:e2e:local): Uses the local version, no build step needed
Integration Modes Tested:
- SDK Mode: Tests toolbar with React SDK integration, flag overrides, and event interception
- Dev Server Mode: Tests toolbar with LaunchDarkly CLI dev server integration
# Run E2E tests against the packaged version
pnpm test:e2e:ci
# Run with UI mode for debugging against the packaged version
pnpm test:e2e:ci:ui
# Run E2E tests against the local version
pnpm test:e2e:local
# Run with UI mode for debugging against the local version
pnpm test:e2e:local:ui
E2E test files location: e2e/tests/
E2E config location: e2e/config/environment.ts
Detailed E2E documentation: See e2e/README.md for comprehensive testing setup and architecture details
- Unit tests should focus on component behavior and logic
- E2E tests should test complete user workflows
- Use React Testing Library for component testing
- Follow the existing test patterns and naming conventions
To build the toolbar for production:
pnpm buildThis creates:
- NPM package (
packages/toolbar/dist/) - ESM/CommonJS bundles and TypeScript declarations - CDN bundle (
packages/toolbar/cdn/) - Minified IIFE bundle for script tags
Publishing is handled automatically via GitHub Actions and release-please. The toolbar package is published from packages/toolbar/ which contains only clean library code (no demo scripts).
Manual publishing (if needed):
# Build and publish the toolbar package
pnpm --filter @launchdarkly/toolbar build
pnpm --filter @launchdarkly/toolbar publish- Functional components with hooks
- Named exports preferred over default exports
- Custom hooks for reusable logic
- Context for shared state (see
SearchProvider,DevServerProvider)
- Vanilla Extract for component-specific styles (zero-runtime CSS-in-JS)
- Type-safe styling with TypeScript integration
- CSS custom properties for theming
- Responsive design considerations
- PascalCase for component files (
LaunchDarklyToolbar.tsx) - camelCase for utility files (
useToolbarState.ts) - Component directories include: main file, styles, tests, index
- Barrel exports from
index.tsfiles
# Linting
pnpm lint
# Formatting
pnpm formatWe use:
- ESLint for linting
- Prettier for code formatting
- TypeScript for type checking
- Run all checks locally:
pnpm build # Ensure builds successfully
pnpm test # Run unit tests
pnpm test:e2e:local # Run E2E tests
pnpm lint # Check for linting issues-
Test your changes:
- Run the demo application
- Test different toolbar configurations
- Verify responsive behavior
- Check accessibility (keyboard navigation)
-
Update documentation:
- Update README.md if adding new features
- Add/update component stories for Storybook
- Update TypeScript types if needed
- Create a feature branch:
git checkout -b feature/your-feature-name-
Make focused commits:
- Each commit should represent a logical change
- Write clear commit messages
- Keep changes focused and atomic
-
Update tests:
- Add tests for new functionality
- Update existing tests if behavior changes
- Ensure all tests pass
-
Write a clear PR description:
- Describe what the change does and why
- Include screenshots for UI changes
- Link to any related issues
Thank you for contributing to LaunchDarkly Toolbar! 🚀