CodeVetter · Repo Unpack · System map
flutter/flutter
The repo is a multi-language monorepo: shell entrypoints (bin/) bootstrap a Dart CLI (packages/flutter_tools), the Dart framework (packages/flutter) is the runtime library apps import, and the engine C++ code (engine/src/flutter) is built with GN and pinned external deps via DEPS. Runtime boundaries are: user shell -> flutter tool process -> device/emulator process running the engine -> Dart isolate running dart:ui + framework. Storage is the local bin/cache directory plus pub caches; external integrations are Google Cloud Storage artifact downloads, pub.dev, Gradle/Xcode toolchains, and the VM service protocol. CI is driven by LUCI via .ci.yaml which defers to dev/bots/test.dart shards; GitHub Actions only runs auxiliary checks.
- bin/flutter resolves its own path through symlinks via follow_links(), sources bin/internal/shared.sh, and calls shared::execute(); on Windows-like shells (MINGW/CYGWIN/MSYS) it execs flutter.bat instead.
- shared::execute() in shared.sh computes FLUTTER_ROOT, runs update_engine_version.sh, downloads the Dart SDK via bin/internal/update_dart_sdk.sh when the snapshot stamp is stale, compiles bin/cache/flutter_tools.snapshot with `dart --snapshot-kind=app-jit`, then execs the snapshot.
- Snapshot invalidation is keyed on `git rev-parse HEAD` + FLUTTER_TOOL_ARGS stored in flutter_tools.stamp, and on pubspec.yaml being newer than pubspec.lock; updates are serialized with a flock/shlock/mkdir lock on fd 7 at bin/cache/.upgrade_lock.
- The Dart-side tool entrypoint is packages/flutter_tools/bin/flutter_tools.dart, which just calls executable.main() in lib/executable.dart; main() builds a context overrides map and the command list via generateCommands(), then calls runner.run().
- runner.run() wraps execution in runInContext and runZonedGuarded, bootstraps ToolDependencies from ~35 globals (fs, platform, processManager, xcode, androidSdk, cache, analytics...), constructs FlutterCommandRunner, registers commands, and funnels all errors through _handleToolError.
- The repo is a pub workspace: root pubspec.yaml lists ~70 workspace members spanning packages/*, dev/*, and examples/*, so a single pub get resolves the whole tree.
- The engine lives in-repo under engine/src/flutter with a GN build (engine/src/flutter/BUILD.gn); third-party revisions (dart_revision, skia_revision, clang_version, reclient) are pinned in DEPS and synced with gclient.
- The Dart<->C++ runtime boundary is dart:ui in engine/src/flutter/lib/ui: functions in hooks.dart are annotated @pragma('vm:entry-point') and are invoked directly by the engine (e.g. _runMain, _addView) to deliver platform events into PlatformDispatcher.
- The embedder boundary is a stable C API in engine/src/flutter/shell/platform/embedder/embedder.h, with per-platform embedders under shell/platform/{android,darwin,windows,linux,fuchsia}; Android's embedder is the Java io.flutter.embedding.engine.FlutterEngine.
- Prebuilt engine artifacts are downloaded by packages/flutter_tools/lib/src/cache.dart from https://storage.googleapis.com (realm- and FLUTTER_STORAGE_BASE_URL-adjustable), organized by DevelopmentArtifact values gated behind Feature flags, and stamped under bin/cache.
- CI source of truth is .ci.yaml (~7800 lines) consumed by LUCI/Cocoon; the flutter_drone recipe defers to dev/bots/test.dart with the shard key; GitHub workflows like tool-test-general.yml only run focused checks (e.g. SHARD=tool_tests SUBSHARD=general).
- Physical-device end-to-end testing runs through dev/devicelab with its own task runner (dev/devicelab/bin/run.dart) and task library.