Home/ Knowledge Base/ Building & running/ Lanes, toolchains & version sources
Building & running

Lanes, toolchains & version sources

A lane is one buildable target: it names a toolchain adapter, its parameters, and where its version number is read and written.

Last updated 2026-07-02

A lane is one buildable target inside a project — an iOS app, an Android app, a web bundle, a desktop build. It answers three questions: how does this build (its toolchain), where does its version number live (its version source), and where does the result go (its distributions). This article covers the first two; distributions have their own article, Build ≠ Distribute.

Anatomy of a lane

Label
A human name — “iOS”, “Android”, “Web”, “Desktop”.
Working directory
Where the build runs, relative to the repo root.
Toolchain
The adapter that knows how to build this stack, plus its parameters.
Version source
The file and format AppRelay reads (and writes) the version from.
Distributions
One or more destinations the build ships to.

Toolchains

A toolchain names an adapter by id and carries that adapter's parameters. Adapters are the thin, compiled-in pieces that know a stack's detection signals, default parameter keys, and which built-in recipe to run. The shipped library:

AdapterForKey parameters
xcodeXcode / Swift appscontainer (project or workspace), scheme, bundleId, teamId
gradleAndroid / Kotlindsl (Groovy/KTS), moduleDir, applicationId
reactNativeBare React Nativeplatform-specific build settings
expoExpo / EASprofile
flutterFluttertarget
nodeWeb (React/Next/Vue/Svelte), static, PWAframework, buildCmd, outDir
electronElectron desktop appsbuild/make settings
tauriTauri desktop appsbundleTargets
macNativemacOS-native apps (DMG, Sparkle appcast)signing/notarize settings
customShellAnything else — you supply the commandsyour steps

Because a lane names its adapter and channels by string id — resolved against a registry — there's no closed list of “platforms” baked in. Stack quirks (Groovy vs. KTS, project vs. workspace, monorepo layouts) are expressed as parameters, not special cases.

Version sources

The version source tells AppRelay exactly where a lane's version number lives, so it can display the current value on the Overview and bump it during a release. Each kind knows how to read and write its own format:

Version kindReads / writes
pbxprojXcode MARKETING_VERSION (and build number)
gradleLiteralA literal versionName / versionCode in Gradle
gradleDerivedA versionName composed from a prefix + versionCode
packageJsonversion in package.json
pubspecversion: in a Flutter pubspec.yaml
cargoTomlversion in Cargo.toml
pyprojectversion in pyproject.toml
expoAppConfigExpo app.json / app.config.*
appcastA Sparkle appcast (for macOS-native)
customRegexYour own read/write regular expressions — the escape hatch for unusual formats
Version writing is format-specific. Bumping pbxproj, KTS, package.json, or pubspec.yaml without corrupting the file is fiddly, so each kind owns its write-back. If your format is unusual, use customRegex, or fall back to a manual bump. If a write ever looks wrong, check it in Source Control before continuing.

Editing a lane

In the project editor's Lanes section each lane is a form: pick the toolchain adapter and fill its parameters, choose the version source, and add the list of distributions (each picking a channel, a recipe, and a signing method). Onboarding prefills all of this from what it detected; you're just confirming or refining.

Next steps