Ecosystems
An ecosystem is a set of target kinds for one language, platform, or build domain. It gives Once enough information to validate dependencies, explain what a target can do, and cache work from declared inputs and outputs.
Choose Between a Typed Target and a Script
Use an ecosystem target kind when Once should understand the artifact and its relationships. This is a good fit when you want to:
- query targets and capabilities before doing work;
- validate dependencies and attributes early;
- reuse build outputs across targets or machines;
- expose focused build, run, and test operations to coding agents.
Use a script target when an existing tool remains the source of truth, the workflow is still exploratory, or the native feature you need has not been modeled. Scripts still participate in the graph, so a project can begin there and adopt typed targets one boundary at a time.
Available Ecosystems
Each supported ecosystem has an incremental guide with a first project, query-before-build workflow, current limitations, and follow-up steps:
- Apple covers libraries, frameworks, applications, and tests written in Swift, Objective-C, C, and C++.
- Android covers resources, Java and Kotlin libraries, application packages, and host or device tests.
- C and C++ covers headers, source compilation, static libraries, and native consumers.
- Elixir covers compiled applications and ExUnit tests.
- Rust covers libraries, binaries, tests, procedural macros, Cargo dependencies, and native mobile outputs.
- Zig covers modules, binaries, tests, libraries, and C or C++ dependencies.
Use the target kind index after choosing an ecosystem. It lists the exact schema, dependencies, capabilities, outputs, and current limitations for every kind.
Shared Mobile Code
Some target kinds cross platform boundaries while preserving normal graph dependencies:
swift_android_librarypackages Swift code for an Android application.kotlin_apple_frameworkproduces a Kotlin/Native framework for an Apple target.rust_mobile_libraryproduces the Apple or Android native library variant requested by its consumer.
Use these after the application builds without shared code. That sequence keeps toolchain and linking problems separate from the first graph setup.
Adopt an Ecosystem Incrementally
- Pick the smallest artifact that has stable inputs and outputs.
- Declare one target and run
once query schema <kind>. - Run
once query capabilities <target>and build that same target. - Connect one consumer through
depsand query the resulting graph. - Add run or test targets only after the artifact build is reliable.
- Keep unsupported edges behind scripts until a typed target kind covers them.
This sequence leaves the native package manager or build system in place for the parts Once does not own. A project does not need to move an entire ecosystem at once.
A coding harness can also fetch the authoritative external rule or plugin, query Once's live module-authoring contract, and maintain that local target kind for the project. This is useful when the project needs a narrow dependency slice and a general built-in integration would be unnecessary. See Coding harnesses.
Check the Boundary Before Adopting
Feature coverage varies by ecosystem. Before moving a production workflow, check the target kind reference for:
- supported source, resource, and dependency shapes;
- ownership of third-party dependency resolution;
- required compilers and platform tools;
- cacheable artifacts and non-cacheable runtime effects;
- unsupported attributes and whether they fail validation;
- editor or language-service integration the existing workflow still needs.
Unsupported does not have to mean blocked. Keep that behavior in a script, define a checked-in local module, or contribute the missing typed behavior. The important part is to keep the boundary visible so readers and agents can tell which system owns each step.
