Welcome back

Opening shared build

Preparing your Mach workspace…

Preparing your secure download…

Documentation
Blog
Open dashboard
Mach Docs

Flutter Projects

Integrate an existing app, then build, sign, test, and release Android and iOS.
Mach supports standalone Flutter applications and apps inside Dart workspaces. Mach uses your committed Flutter, Gradle, CocoaPods, and Xcode projects directly. It does not regenerate `lib`, `android`, or `ios`, and JavaScript tooling never enters a Flutter build.
Read the complete existing-project Flutter integration tutorial →
1. Validate, Initialize, or Link
Start from a working app and clean Git diff. Run `mach init` from the repository root to create a Dashboard project, or `mach link` when that project already exists. Both detect `pubspec.yaml`, native identifiers, `appDirectory`, and the active Flutter SDK. Linking preserves existing profile names and custom configuration.
flutter --version
flutter doctor -v
flutter pub get
flutter analyze
flutter test
npm install -g @radhya/mach@latest
mach login
# Create a new Dashboard project
mach init
# OR connect an existing Dashboard project
mach link
Keep the generated `projectId` unchanged. Commit `mach.config.json` and the application's `pubspec.lock`.
2. Profile-Driven Configuration
Profile names are labels, not reserved behavior. Add as many uniquely named profiles as the project needs; `environment`, `distribution`, platform fields, and the nested `flutter` object control each build. Preserve package and bundle identifiers already used by an existing app. A flavor is optional, and target defaults to `lib/main.dart`.
mach.config.json
{
"framework": "flutter",
"appDirectory": ".",
"flutter": { "sdkVersion": "3.47.1" },
"ios": {
"bundleIdentifier": "com.example.app",
"buildNumber": "auto"
},
"android": {
"package": "com.example.app",
"versionCode": "auto"
},
"build": {
"team-staging": {
"environment": "staging",
"distribution": "internal",
"ios": { "bundleIdentifier": "com.example.app.staging" },
"android": { "package": "com.example.app.staging" },
"flutter": {
"flavor": "staging",
"target": "lib/main_staging.dart",
"mode": "release",
"dartDefinesFromEnv": ["API_URL", "APP_ENV"]
}
},
"store-release": {
"environment": "production",
"distribution": "store",
"flutter": {
"flavor": "production",
"target": "lib/main_production.dart",
"mode": "release",
"dartDefinesFromEnv": ["API_URL", "APP_ENV"]
}
}
}
}
Values passed with `dartDefinesFromEnv` are compiled into the app. Use them for configuration, never for secrets.
3. Native Identity and Flavor Mapping
Mach selects flavors and Xcode schemes already defined by the app; it does not create them. Shared `flutter` fields apply to both platforms. When Android and iOS use different flavor names, place an overriding `flutter` object inside the platform configuration. The target must be relative to `appDirectory` and stay inside it.
Different native flavor names
{
"build": {
"preprod-client": {
"environment": "staging",
"distribution": "internal",
"flutter": {
"target": "lib/main_preprod.dart",
"mode": "release"
},
"android": {
"package": "com.example.app.preprod",
"flutter": { "flavor": "preprod" }
},
"ios": {
"bundleIdentifier": "com.example.app.preprod",
"iosConfiguration": "Release-PreProd",
"flutter": { "flavor": "PreProd" }
}
}
}
}
For a published app, copy identifiers from the working native targets or store records. Changing them creates a different app and changes credential and version-counter scope.
4. Environment Values and Dart Defines
`environment` selects the matching Dashboard environment. `dartDefinesFromEnv` is an allowlist of variable names passed to Flutter as `--dart-define`. Add scoped values in the Dashboard Secrets page and use `mach env list` to confirm their names.
mach env list
mach config --profile team-staging
Dart defines are compiled into the app. Use them for API URLs, environment names, and public flags—not passwords, private keys, bearer tokens, service-account files, or signing material.
5. Audit and Inspect Before Building
`mach audit` checks the SDK pin, Dart constraint, Flutter doctor, static analysis, lockfile, dependency health, targets, Android flavors, native permissions, and release impact. `mach config` shows the fully merged profile, including inheritance and platform overrides. Run both before allocating a managed runner.
mach audit
mach config --profile team-staging
mach config --profile store-release --json
# CI-friendly audit
mach audit --json --severity high
6. What Mach Manages
APK, AAB, and IPA
Internal Android builds produce APK files, store builds produce AAB files, and iOS uses Mach's signed archive and IPA pipeline.
Pinned Toolchain
Managed runners resolve the exact Flutter SDK from the official archive manifest and verify its SHA-256 checksum.
Native Versioning
Dashboard counters become Flutter build numbers and are verified against the final APK, AAB, or IPA.
Early Validation
Invalid flavors, targets, SDK pins, and unsupported add-to-app modules fail before a cloud runner is allocated.
7. Credentials and Existing Store Versions
Configure credentials with the same profile you plan to build. Mach resolves that profile's identifier and distribution before selecting an Android keystore or iOS certificate and provisioning profile. If the app is already published, seed each native counter with the latest number already used by its store before the first auto-versioned build.
mach credentials --profile team-staging
mach credentials --profile store-release
# Example: latest values already consumed by the stores
mach version seed --platform android --profile store-release --value 42
mach version seed --platform ios --profile store-release --value 108
mach version show --platform android --profile store-release
mach version show --platform ios --profile store-release
Seed the latest already-used value, not the value you want next. Mach increments it for the following build. The marketing version remains in `pubspec.yaml`.
8. Local, Cloud, and Store Delivery
Use a local build to prove a new profile with your installed Flutter and native toolchains. Managed builds activate the pinned SDK, restore isolated caches, inject temporary signing material, validate the artifact, and publish logs plus resolved Flutter metadata to the Dashboard. Internal Android builds default to APK; store builds default to AAB.
# Profile-aware development and local proof
mach start --profile team-staging
mach build --platform android --profile team-staging --local
# Managed signed builds
mach build --platform android --profile team-staging
mach build --platform ios --profile store-release
# Store service credentials and submission
mach credentials:service --platform android --profile store-release --file ~/Downloads/play-service-account.json
mach credentials:service --platform ios --profile store-release
mach submit --latest --platform android --profile store-release --track internal
mach submit --latest --platform ios --profile store-release
Open [Configuration] for every root, platform, and Flutter profile field.
9. Monorepos and CI
Keep `mach.config.json` at the source snapshot root and set `appDirectory` to the folder containing the Flutter app. Mach uploads the repository root so Dart workspace packages remain available, but runs Flutter from `appDirectory`. In CI, authenticate with a protected `MACH_TOKEN`, commit the lockfile, and always select an explicit profile.
Workspace layout
{
"framework": "flutter",
"appDirectory": "apps/mobile",
"flutter": { "sdkVersion": "3.47.1" }
}
CI
export MACH_TOKEN="$MACH_TOKEN"
npm install -g @radhya/mach@latest
mach audit --severity high
mach build --platform android --profile store-release --json-output mach-android-build.json
10. Fast Troubleshooting
Start with `mach audit` and the resolved profile. SDK mismatches require activating the pinned Flutter version or intentionally updating the pin. Flavor failures require an existing Android product flavor and iOS shared scheme with matching capitalization. Missing Dart defines must be added to the selected Dashboard environment. Credential errors usually mean the stored material targets another identifier or distribution.
mach audit
mach config --profile team-staging
flutter --version
flutter doctor -v
flutter analyze
Current Scope
Flutter Android, iOS, and web builds, credentials, versioning, audits, local or managed execution, artifacts, Maestro and Playwright tests, deep-link configuration, MACH Push, customer-owned Shorebird OTA, release symbols, and store submissions are supported. Add-to-app hosts remain outside the current build contract. Expo Router sitemap generation remains Expo-specific and stops early for Flutter.
Previous
Expo projects
Next
OTA updates