Ensemble is a Flutter/Dart monorepo (managed by Melos) that provides a runtime for building native apps from declarative YAML definitions. The starter app (/starter) is the primary runnable application.
- Flutter SDK 3.47.2 must be installed at
/opt/flutterwith/opt/flutter/binonPATH. Every CI workflow pins it;build.ymladditionally builds the starter on 3.38.7.modules/ensembledeclaresflutter: ">=3.27.0"and was verified manually on 3.27.4, 3.35.4 and 3.47.2 — do not introduce APIs newer than 3.27 there without raising that floor (see theTODO(flutter-upgrade)markers). - CI does not test 3.27:
modules/auth,modules/chatandmodules/ensemble_bluetoothdeclarecollection: ^1.19.1/meta: ^1.16.0, which Flutter 3.27 cannot satisfy (it pinscollection 1.19.0andmeta 1.15.0exactly). Pre-existing, unrelated to the core runtime — those modules are opt-in andmodules/ensembledoes not depend on them. - JDK 17 is required for Android builds (Flutter 3.38 raised the minimum).
- Melos must be globally activated (
dart pub global activate melos). PATHmust include both/opt/flutter/binand$HOME/.pub-cache/bin.
| Task | Command | Working directory |
|---|---|---|
| Bootstrap monorepo | melos bootstrap |
/workspace |
| Lint (core module) | flutter analyze |
/workspace/modules/ensemble |
| Lint (starter) | flutter analyze |
/workspace/starter |
| Unit tests (core) | flutter test |
/workspace/modules/ensemble |
| Unit tests (auth) | flutter test |
/workspace/modules/auth |
| Build web | flutter build web --no-tree-shake-icons |
/workspace/starter |
| Run web dev server | flutter run -d web-server --web-port=8080 --web-hostname=0.0.0.0 |
/workspace/starter |
- The starter's
pubspec.yamlpoints theensembledependency to a git URL, butmelos bootstrapoverrides this with a local path reference. Always runmelos bootstrapfrom the repo root before building. - The default
ensemble-config.yamlusesfrom: ensemblewhich fetches app definitions from Ensemble's cloud (Firestore). This works without any local Firebase setup since it reads from a public Kitchen Sink demo app (appId: e24402cb-75e2-404c-866c-29e6c3dd7992). - To use local YAML definitions instead, change
from: ensembletofrom: localinstarter/ensemble/ensemble-config.yaml. flutter analyzereports ~237 pre-existing issues inmodules/ensemble(0 errors; mostlymust_be_immutable, unused imports/locals, and ~22 remaining deprecations). These are not regressions.- iOS/Android release builds need
--no-tree-shake-icons: Ensemble resolves icons dynamically from YAML, so it builds non-constIconData(seemodules/ensemble/lib/framework/widget/icon.dart). - The starter is deliberately incomplete in git:
.gitignoreexcludes both the Xcode project (project.pbxproj) and the AndroidMainActivity(starter/android/app/src/main/kotlin). Before building either platform, run the generate step from the starter README:cd starter && flutter create --org com.ensembleui --project-name starter --platform=ios,android,web .The project name must yieldcom.ensembleui.starterto matchappIdinensemble/ensemble.properties, otherwise the app installs but crashes withClassNotFoundException ... MainActivity. - Before an iOS build on Flutter >= 3.44, disable SwiftPM:
flutter config --no-enable-swift-package-manager. 10 plugins have no SwiftPM support, and running it alongside CocoaPods makes Xcode fail with "Multiple commands produce ...framework" for the Firebase/gRPC frameworks. Not set inpubspec.yamlon purpose: theflutter: config:key only parses on Flutter >= 3.44 and would break the 3.27 target. CI is unaffected (it builds web + android only). - Web builds produce Wasm compatibility warnings for packages using
dart:html— these are informational and do not block the JS build. - The Chrome device (
-d chrome) opens a browser window; use-d web-serverfor headless/CI environments. - After changing dependencies in any module's
pubspec.yaml, re-runmelos bootstrapfrom the repo root. - After switching Flutter SDKs (
fvm use), runflutter cleanbefore testing — a stale per-SDKshaders/ink_sparkle.fragmakes unrelated widget tests fail with "Runtime stages buffer failed verification".