This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a Melos-managed Dart/Flutter monorepo that publishes launchdarkly_flutter_client_sdk along with its supporting packages.
packages/common(launchdarkly_dart_common) — Dart-only code usable by both client-side and server-side SDKs (contexts,LDValue, logging, events, env reporting, serialization, network helpers).packages/common_client(launchdarkly_common_client) — client-side SDK code that is not Flutter-specific (flag manager, data sources, hooks, plugins, persistence interface,LDCommonClient).packages/event_source_client(launchdarkly_event_source_client) — SSE client implementation used by the streaming data source.packages/flutter_client_sdk(launchdarkly_flutter_client_sdk) — the published Flutter SDK. WrapsLDCommonClientand provides Flutter-specificPersistence(shared_preferences), env reporter (package_info_plus/device_info_plus), state detection (connectivity_plus+ lifecycle), and aConnectionManager.apps/sse_contract_test_serviceandapps/flutter_client_contract_test_service— test service harnesses driven by LaunchDarkly's centralized contract test runners.architechture/— Mermaid diagrams describing high-level architecture and theidentifyflow. Note the misspelling of the directory.
Inter-package dependencies are pinned to exact versions in pubspec.yaml files. See RELEASING.md: a change to common requires a release-in-dependency-order (common → common_client → flutter_client_sdk), with a manual PR between each release to bump the pinned version.
All commands are run from the repo root and go through Melos.
dart pub global activate melos # one-time
melos bootstrap # install deps for every package
melos run analyze # dart analyze --fatal-infos across all packages
melos run fix # dart fix --apply
melos run test # runs `flutter test --coverage` in common, common_client, flutter_client_sdk
melos run sse-contract-tests # start SSE contract service and run the v2 harness
melos run client-contract-tests # start Flutter client contract service and run the SDK harness
melos run coverage-report # merge lcov files and show coverage value (requires `dart pub global activate coverde`)
melos run coverage-report-html # same, but emits HTML to coverage/html/
melos run launchdarkly_flutter_example # build/run the example app for manual testing
To run a single test file, cd into the package and use Flutter directly, e.g. cd packages/common_client && flutter test test/path/to/file_test.dart. The melos run test target only covers launchdarkly_dart_common, launchdarkly_common_client, and launchdarkly_flutter_client_sdk — event_source_client tests are not yet wired in.
The Flutter SDK is a thin adapter layer around LDCommonClient (in common_client). LDClient in packages/flutter_client_sdk/lib/src/ld_client.dart constructs a CommonPlatform with platform-specific implementations and delegates flag evaluation, identify, events, and data source management to the common client.
Key collaborators inside LDCommonClient:
- FlagManager owns
FlagStore(in-memory flag cache),FlagUpdater(emitsFlagsChangedEvents), andFlagPersistence(writes through to aPersistenceimplementation). - DataSourceManager selects between
StreamingDataSource(SSE, viaevent_source_client) andPollingDataSourcebased onConnectionMode, and routes updates throughDataSourceEventHandlerinto theFlagManager. - Context modifiers (anonymous key generation, auto-env attributes) mutate the inbound
LDContextbefore evaluation. - Hooks and plugins wrap variation/identify/track calls; plugins can also contribute hooks (see
safeGetHooks+combineHooksused byLDClient).
Flutter-specific additions layered on top:
SharedPreferencesPersistenceimplements thePersistenceinterface.PlatformEnvReporterimplementsEnvironmentReporterusingpackage_info_plus/device_info_plus.FlutterStateDetectorcombinesconnectivity_pluswith app lifecycle events to feed theConnectionManager, which switchesConnectionMode(streaming / polling / offline) based on foreground/background and network state.
See architechture/high_level.md for the class diagram and architechture/identify.md for the identify sequence.
- Follow
common_analysis.yaml: relative imports inside a package'slib/, single quotes, explicit return types, and close yourStreamSinks. - Code changes use Conventional Commits (
feat:,fix:,chore:, …). Release PRs are produced by release-please and the flow is described inRELEASING.md. The SDK version string inpackages/flutter_client_sdk/lib/src/ld_client.dartcarries a// x-release-please-versionmarker — do not edit it manually. - Public API from
commonandcommon_clientis re-exported throughpackages/common_client/lib/launchdarkly_common_client.dart; when adding new public types, add them to that export list so the Flutter package can surface them. - Null narrowing: prefer Dart 3 case-patterns over the
!operator. Useif (x case final v?) { ... v ... }instead ofif (x != null) { ... x! ... }, and combine withwhenfor extra guards (if (s.state case final state? when state.isNotEmpty)). The case-pattern introduces a non-null local without runtime assertion. - Capturing log output in tests: use
mocktail'sMock implements LDLogAdapterplusverify(() => adapter.log(captureAny())).capturedrather than hand-rolling a capturing adapter. Seepackages/common_client/test/persistence/validating_persistence_test.dartfor the canonical setup (including theregisterFallbackValue(LDLogRecord(...))insetUpAll).