Toolchains
Terminology: This specification uses RFC 2119 keywords (MUST, SHOULD, MAY, etc.) to indicate requirement levels.
This document defines the built-in toolchain presets for Structyl.
Non-Goals
This specification does not cover:
- Build tool installation: Toolchains assume tools are already installed. Use mise for tool version management.
- Custom build pipelines: Toolchains provide standard command mappings; complex orchestration belongs in target configuration.
- IDE integration: Toolchain definitions are for CLI execution, not IDE project files.
- Dependency resolution: Toolchains invoke package managers but don't manage transitive dependencies.
Overview
A toolchain is a preset that provides default commands for a specific build ecosystem. Toolchains eliminate boilerplate by mapping Structyl's standard command vocabulary to ecosystem-specific invocations.
Structyl includes 27 built-in toolchains covering major programming languages and build systems.
Usage
Specify the toolchain in target configuration:
{
"targets": {
"rs": {
"type": "language",
"title": "Rust",
"toolchain": "cargo"
}
}
}If toolchain is omitted, Structyl attempts auto-detection based on files in the target directory.
Auto-Detection
Structyl checks for marker files in order:
| File | Toolchain |
|---|---|
Cargo.toml | cargo |
go.mod | go |
deno.jsonc, deno.json | deno |
pnpm-lock.yaml | pnpm |
yarn.lock | yarn |
bun.lockb | bun |
package.json | npm |
uv.lock | uv |
poetry.lock | poetry |
pyproject.toml, setup.py | python |
build.gradle.kts, build.gradle | gradle |
pom.xml | maven |
build.sbt | sbt |
Package.swift | swift |
CMakeLists.txt | cmake |
Makefile | make |
*.sln, Directory.Build.props, global.json | dotnet |
*.csproj, *.fsproj | dotnet |
Gemfile | bundler |
composer.json | composer |
mix.exs | mix |
stack.yaml | stack |
*.cabal | cabal |
dune-project | dune |
project.clj | lein |
build.zig | zig |
rebar.config | rebar3 |
DESCRIPTION | r |
Detection Algorithm
- For each marker pattern in the table above (checked in listed order):
- If the pattern contains
*(glob): check if any files match the glob in the target directory - Otherwise: check if the exact file exists in the target directory
- Return the toolchain for the first match found
- If no patterns match, the toolchain is undefined (requires explicit
toolchainconfiguration)
Glob patterns: Entries marked with * (e.g., *.csproj) use glob matching. For example, *.csproj matches any file ending in .csproj in the target directory.
Explicit toolchain declaration is RECOMMENDED for clarity and to avoid detection order surprises.
Standard Command Vocabulary
All toolchains implement this vocabulary:
| Command | Purpose |
|---|---|
clean | Clean build artifacts |
restore | Restore/install dependencies |
build | Build targets |
build:release | Build targets (release mode)† |
test | Run tests |
test:coverage | Run tests with coverage (optional, see ‡) |
check | Run static analysis (lint, typecheck, format-check)* |
check:fix | Auto-fix static analysis issues |
bench | Run benchmarks |
demo | Run demos |
doc | Generate documentation |
pack | Create package |
publish | Publish package to registry |
publish:dry | Dry-run publish (validate without uploading) |
| Command | Purpose |
|---|---|
clean | Clean build artifacts |
restore | Restore/install dependencies |
build | Build targets |
build:release | Build targets (release mode) |
test | Run tests |
test:coverage | Run tests with coverage |
check | Run static analysis (lint, typecheck, format-check) |
check:fix | Auto-fix static analysis issues |
bench | Run benchmarks |
demo | Run demos |
doc | Generate documentation |
pack | Create package |
publish | Publish package to registry |
publish:dry | Dry-run publish (validate without uploading) |
† build:release is only provided by toolchains with distinct release/optimized build modes (e.g., cargo, dotnet, swift, make, zig). Toolchains that use configuration-time flags rather than build-time flags for release mode (e.g., cmake which uses -DCMAKE_BUILD_TYPE=Release at configure time) do not define this variant.
cmake users: For release builds with cmake, specify the build type during configuration:
cmake -B build -S . -DCMAKE_BUILD_TYPE=Release. Therestorecommand runs the default configure step; override it in target configuration to include release flags.
‡ test:coverage is OPTIONAL. No built-in toolchain provides a default implementation because coverage tools vary significantly by ecosystem. Configure a custom test:coverage command in target configuration if needed. See commands.md for semantics.
* check composition varies by toolchain. Some include all three components (lint, typecheck, format-check), others include subsets based on ecosystem conventions and available tools. See individual toolchain sections for exact composition.
Command availability: Not all toolchains implement every command. Commands like
doc,pack,publish,demo, andbenchdepend on ecosystem support. See individual toolchain sections (e.g., Cargo, Go) for exact command mappings. Unavailable commands are set tonull(invoking them succeeds with a warning).
check Composition Summary
Table notation: In command tables below,
—(em-dash) indicates the command is not available for this toolchain (equivalent tonullin configuration). Invoking anullcommand succeeds with a warning:command "X" is not available.
| Toolchain | Lint | Typecheck | Format-check |
|---|---|---|---|
cargo | ✓ (clippy) | — | ✓ |
dotnet | — | — | ✓ |
go | ✓ (golangci-lint, vet) | — | ✓ |
npm | ✓ | ✓ | ✓ |
pnpm | ✓ | ✓ | ✓ |
yarn | ✓ | ✓ | ✓ |
bun | ✓ | ✓ | ✓ |
python | ✓ (ruff) | ✓ (mypy) | ✓ |
uv | ✓ (ruff) | ✓ (mypy) | ✓ |
poetry | ✓ (ruff) | ✓ (mypy) | ✓ |
gradle | ✓ (check) | — | ✓ (spotless) |
maven | ✓ (checkstyle) | — | ✓ (spotless) |
make | ✓ | — | — |
cmake | ✓ | — | ✓ |
swift | ✓ (swiftlint) | — | ✓ (swiftformat) |
deno | ✓ | ✓ | ✓ |
r | ✓ (lintr) | — | ✓ (styler) |
bundler | ✓ (rubocop) | — | — |
composer | ✓ | — | ✓ |
mix | ✓ (credo) | ✓ (dialyzer) | ✓ |
sbt | — | — | ✓ (scalafmt) |
cabal | ✓ (hlint, check) | — | ✓ (ormolu) |
stack | ✓ (hlint) | — | ✓ (ormolu) |
dune | — | — | ✓ |
lein | ✓ (check, eastwood) | — | ✓ (cljfmt) |
zig | — | — | ✓ |
rebar3 | ✓ (dialyzer, lint) | — | — |
Commands not applicable to a toolchain are set to null (skipped).
Note: The
test:coveragecommand (marked with ‡ in the vocabulary table) is intentionally omitted from this composition table. No built-in toolchain providestest:coverage—projects MUST define custom implementations using language-specific coverage tools (e.g.,cargo-tarpaulin,go test -cover,coverage.py).
Note: For
check:fixcompositions (auto-fix behavior), see the summary table below. Most toolchains run format commands as part ofcheck:fix, with some also including lint auto-fix.
check:fix Composition Summary
| Toolchain | Auto-fix Components |
|---|---|
cargo | cargo fmt |
dotnet | dotnet format |
go | go fmt ./... |
npm | npm run lint -- --fix + npm run format |
pnpm | pnpm lint --fix + pnpm format |
yarn | yarn lint --fix + yarn format |
bun | bun run lint --fix + bun run format |
python | ruff check --fix . + ruff format . |
uv | uv run ruff check --fix . + uv run ruff format . |
poetry | poetry run ruff check --fix . + poetry run ruff format . |
gradle | gradle spotlessApply |
maven | mvn spotless:apply |
make | make fix |
cmake | cmake --build build --target format |
swift | swiftlint --fix + swiftformat . |
deno | deno fmt |
r | Rscript -e "styler::style_pkg()" |
bundler | bundle exec rubocop -a |
composer | composer run-script format |
mix | mix format |
sbt | sbt scalafmt |
cabal | ormolu --mode inplace $(find . -name '*.hs') |
stack | stack exec -- ormolu --mode inplace $(find . -name '*.hs') |
dune | dune fmt |
lein | lein cljfmt fix |
zig | zig fmt . |
rebar3 | rebar3 format |
Execution order: When commands are composed from multiple operations (e.g.,
check= lint + format-check), they execute left-to-right as listed in the Implementation column. Forcheck:fix, this typically means lint auto-fix runs before formatting.
Fail-fast behavior: Composite commands execute with fail-fast semantics. If any component fails, subsequent components are not executed. For example, if
lint --fixin acheck:fixcomposition fails, theformatstep is skipped.
Built-in Toolchains
cargo
Ecosystem: Rust
| Command | Implementation |
|---|---|
clean | cargo clean |
restore | — |
build | cargo build |
build:release | cargo build --release |
test | cargo test |
check | cargo clippy -- -D warnings + cargo fmt --check |
check:fix | cargo fmt |
bench | cargo bench |
demo | cargo run --example demo |
doc | cargo doc --no-deps |
pack | cargo package |
publish | cargo publish |
publish:dry | cargo publish --dry-run |
| Command | Implementation |
|---|---|
clean | cargo clean |
restore | — |
build | cargo build |
build:release | cargo build --release |
test | cargo test |
check | cargo clippy -- -D warnings + cargo fmt --check |
check:fix | cargo fmt |
bench | cargo bench |
demo | cargo run --example demo |
doc | cargo doc --no-deps |
pack | cargo package |
publish | cargo publish |
publish:dry | cargo publish --dry-run |
dotnet
Ecosystem: .NET (C#, F#, VB)
| Command | Implementation |
|---|---|
clean | dotnet clean |
restore | dotnet restore |
build | dotnet build |
build:release | dotnet build -c Release |
test | dotnet test |
check | dotnet format --verify-no-changes |
check:fix | dotnet format |
bench | — |
demo | dotnet run --project Demo |
doc | — |
pack | dotnet pack |
publish | dotnet nuget push |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | dotnet clean |
restore | dotnet restore |
build | dotnet build |
build:release | dotnet build -c Release |
test | dotnet test |
check | dotnet format --verify-no-changes |
check:fix | dotnet format |
bench | — |
demo | dotnet run --project Demo |
doc | — |
pack | dotnet pack |
publish | dotnet nuget push |
publish:dry | — |
go
Ecosystem: Go
| Command | Implementation |
|---|---|
clean | go clean |
restore | go mod download |
build | go build ./... |
build:release | — |
test | go test ./... |
check | golangci-lint run + go vet ./... + test -z "$(gofmt -l .)" |
check:fix | go fmt ./... |
bench | go test -bench=. ./... |
demo | go run ./cmd/demo |
doc | go doc ./... |
pack | — |
publish | — |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | go clean |
restore | go mod download |
build | go build ./... |
test | go test ./... |
check | golangci-lint run + go vet ./... + test -z "$(gofmt -l .)" |
check:fix | go fmt ./... |
bench | go test -bench=. ./... |
demo | go run ./cmd/demo |
doc | go doc ./... |
pack | — |
publish | — |
publish:dry | — |
- Note:
lintrequiresgolangci-lintto be installed - Note: Go does not have a distinct release build mode. Use
-ldflagsor build tags for production builds.
Note for Node.js toolchains (npm, pnpm, yarn, bun): Commands like
clean,lint,typecheck, andformatassume corresponding scripts are defined inpackage.json. Missing scripts result in skip errors.
npm
Ecosystem: Node.js (npm)
| Command | Implementation |
|---|---|
clean | npm run clean |
restore | npm ci |
build | npm run build |
build:release | — |
test | npm test |
check | npm run lint + npm run typecheck + npm run format:check |
check:fix | npm run lint -- --fix + npm run format |
bench | — |
demo | npm run demo |
doc | — |
pack | npm pack |
publish | npm publish |
publish:dry | npm publish --dry-run |
| Command | Implementation |
|---|---|
clean | npm run clean |
restore | npm ci |
build | npm run build |
test | npm test |
check | npm run lint + npm run typecheck + npm run format:check |
check:fix | npm run lint -- --fix + npm run format |
bench | — |
demo | npm run demo |
doc | — |
pack | npm pack |
publish | npm publish |
publish:dry | npm publish --dry-run |
pnpm
Ecosystem: Node.js (pnpm)
| Command | Implementation |
|---|---|
clean | pnpm run clean |
restore | pnpm install --frozen-lockfile |
build | pnpm build |
build:release | — |
test | pnpm test |
check | pnpm lint + pnpm typecheck + pnpm format:check |
check:fix | pnpm lint --fix + pnpm format |
bench | — |
demo | pnpm run demo |
doc | — |
pack | pnpm pack |
publish | pnpm publish |
publish:dry | pnpm publish --dry-run |
| Command | Implementation |
|---|---|
clean | pnpm run clean |
restore | pnpm install --frozen-lockfile |
build | pnpm build |
test | pnpm test |
check | pnpm lint + pnpm typecheck + pnpm format:check |
check:fix | pnpm lint --fix + pnpm format |
bench | — |
demo | pnpm run demo |
doc | — |
pack | pnpm pack |
publish | pnpm publish |
publish:dry | pnpm publish --dry-run |
yarn
Ecosystem: Node.js (Yarn)
| Command | Implementation |
|---|---|
clean | yarn clean |
restore | yarn install --frozen-lockfile |
build | yarn build |
build:release | — |
test | yarn test |
check | yarn lint + yarn typecheck + yarn format:check |
check:fix | yarn lint --fix + yarn format |
bench | — |
demo | yarn run demo |
doc | — |
pack | yarn pack |
publish | yarn npm publish |
publish:dry | yarn npm publish --dry-run |
| Command | Implementation |
|---|---|
clean | yarn clean |
restore | yarn install --frozen-lockfile |
build | yarn build |
test | yarn test |
check | yarn lint + yarn typecheck + yarn format:check |
check:fix | yarn lint --fix + yarn format |
bench | — |
demo | yarn run demo |
doc | — |
pack | yarn pack |
publish | yarn npm publish |
publish:dry | yarn npm publish --dry-run |
bun
Ecosystem: Bun
| Command | Implementation |
|---|---|
clean | bun run clean |
restore | bun install --frozen-lockfile |
build | bun run build |
build:release | — |
test | bun test |
check | bun run lint + bun run typecheck + bun run format:check |
check:fix | bun run lint --fix + bun run format |
bench | — |
demo | bun run demo |
doc | — |
pack | bun pm pack |
publish | bun publish |
publish:dry | bun publish --dry-run |
| Command | Implementation |
|---|---|
clean | bun run clean |
restore | bun install --frozen-lockfile |
build | bun run build |
test | bun test |
check | bun run lint + bun run typecheck + bun run format:check |
check:fix | bun run lint --fix + bun run format |
bench | — |
demo | bun run demo |
doc | — |
pack | bun pm pack |
publish | bun publish |
publish:dry | bun publish --dry-run |
python
Ecosystem: Python (pip/setuptools)
| Command | Implementation |
|---|---|
clean | rm -rf dist/ build/ *.egg-info **/__pycache__/ |
restore | pip install -e . |
build | python -m build |
build:release | — |
test | pytest |
check | ruff check . + mypy . + ruff format --check . |
check:fix | ruff check --fix . + ruff format . |
bench | — |
demo | python demo.py |
doc | — |
pack | python -m build |
publish | twine upload dist/* |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | rm -rf dist/ build/ *.egg-info **/__pycache__/ |
restore | pip install -e . |
build | python -m build |
test | pytest |
check | ruff check . + mypy . + ruff format --check . |
check:fix | ruff check --fix . + ruff format . |
bench | — |
demo | python demo.py |
doc | — |
pack | python -m build |
publish | twine upload dist/* |
publish:dry | — |
- Note: Assumes
ruffandmypyare installed
uv
Ecosystem: Python (uv)
| Command | Implementation |
|---|---|
clean | rm -rf dist/ build/ *.egg-info .venv/ |
restore | uv sync --all-extras |
build | uv build |
build:release | — |
test | uv run pytest |
check | uv run ruff check . + uv run mypy . + uv run ruff format --check . |
check:fix | uv run ruff check --fix . + uv run ruff format . |
bench | — |
demo | uv run python demo.py |
doc | — |
pack | uv build |
publish | uv publish |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | rm -rf dist/ build/ *.egg-info .venv/ |
restore | uv sync --all-extras |
build | uv build |
test | uv run pytest |
check | uv run ruff check . + uv run mypy . + uv run ruff format --check . |
check:fix | uv run ruff check --fix . + uv run ruff format . |
bench | — |
demo | uv run python demo.py |
doc | — |
pack | uv build |
publish | uv publish |
publish:dry | — |
poetry
Ecosystem: Python (Poetry)
| Command | Implementation |
|---|---|
clean | rm -rf dist/ |
restore | poetry install |
build | poetry build |
build:release | — |
test | poetry run pytest |
check | poetry run ruff check . + poetry run mypy . + poetry run ruff format --check . |
check:fix | poetry run ruff check --fix . + poetry run ruff format . |
bench | — |
demo | poetry run python demo.py |
doc | — |
pack | poetry build |
publish | poetry publish |
publish:dry | poetry publish --dry-run |
| Command | Implementation |
|---|---|
clean | rm -rf dist/ |
restore | poetry install |
build | poetry build |
test | poetry run pytest |
check | poetry run ruff check . + poetry run mypy . + poetry run ruff format --check . |
check:fix | poetry run ruff check --fix . + poetry run ruff format . |
bench | — |
demo | poetry run python demo.py |
doc | — |
pack | poetry build |
publish | poetry publish |
publish:dry | poetry publish --dry-run |
gradle
Ecosystem: JVM (Gradle)
| Command | Implementation |
|---|---|
clean | gradle clean |
restore | — |
build | gradle build -x test |
build:release | — |
test | gradle test |
check | gradle check -x test + gradle spotlessCheck |
check:fix | gradle spotlessApply |
bench | — |
demo | gradle run |
doc | gradle javadoc |
pack | gradle jar |
publish | gradle publish |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | gradle clean |
restore | — |
build | gradle build -x test |
test | gradle test |
check | gradle check -x test + gradle spotlessCheck |
check:fix | gradle spotlessApply |
bench | — |
demo | gradle run |
doc | gradle javadoc |
pack | gradle jar |
publish | gradle publish |
publish:dry | — |
- Note: Use
./gradlewif wrapper present
maven
Ecosystem: JVM (Maven)
| Command | Implementation |
|---|---|
clean | mvn clean |
restore | mvn dependency:resolve |
build | mvn compile |
build:release | — |
test | mvn test |
check | mvn checkstyle:check + mvn spotless:check |
check:fix | mvn spotless:apply |
bench | — |
demo | mvn exec:java |
doc | mvn javadoc:javadoc |
pack | mvn package -DskipTests |
publish | mvn deploy |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | mvn clean |
restore | mvn dependency:resolve |
build | mvn compile |
test | mvn test |
check | mvn checkstyle:check + mvn spotless:check |
check:fix | mvn spotless:apply |
bench | — |
demo | mvn exec:java |
doc | mvn javadoc:javadoc |
pack | mvn package -DskipTests |
publish | mvn deploy |
publish:dry | — |
- Note:
formatandformat-checkrequire the Spotless Maven plugin
make
Ecosystem: Generic (Make)
| Command | Implementation |
|---|---|
clean | make clean |
restore | — |
build | make |
build:release | make release |
test | make test |
check | make check |
check:fix | make fix |
bench | make bench |
demo | make demo |
doc | make doc |
pack | make dist |
publish | make publish |
publish:dry | make publish-dry |
| Command | Implementation |
|---|---|
clean | make clean |
restore | — |
build | make |
build:release | make release |
test | make test |
check | make check |
check:fix | make fix |
bench | make bench |
demo | make demo |
doc | make doc |
pack | make dist |
publish | make publish |
publish:dry | make publish-dry |
- Note: Assumes Makefile defines corresponding targets
cmake
Ecosystem: C/C++ (CMake)
| Command | Implementation |
|---|---|
clean | cmake --build build --target clean |
restore | cmake -B build -S . |
build | cmake --build build |
build:release | — |
test | ctest --test-dir build |
check | cmake --build build --target lint + cmake --build build --target format-check |
check:fix | cmake --build build --target format |
bench | — |
demo | cmake --build build --target demo && ./build/demo |
doc | cmake --build build --target doc |
pack | cmake --build build --target package |
publish | — |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | cmake --build build --target clean |
restore | cmake -B build -S . |
build | cmake --build build |
test | ctest --test-dir build |
check | cmake --build build --target lint + cmake --build build --target format-check |
check:fix | cmake --build build --target format |
bench | — |
demo | cmake --build build --target demo && ./build/demo |
doc | cmake --build build --target doc |
pack | cmake --build build --target package |
publish | — |
publish:dry | — |
- Note:
lint,format, andformat-checkrequire corresponding CMake targets to be defined
swift
Ecosystem: Swift
| Command | Implementation |
|---|---|
clean | swift package clean |
restore | swift package resolve |
build | swift build |
build:release | swift build -c release |
test | swift test |
check | swiftlint + swiftformat --lint . |
check:fix | swiftlint --fix + swiftformat . |
bench | — |
demo | swift run Demo |
doc | — |
pack | — |
publish | — |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | swift package clean |
restore | swift package resolve |
build | swift build |
build:release | swift build -c release |
test | swift test |
check | swiftlint + swiftformat --lint . |
check:fix | swiftlint --fix + swiftformat . |
bench | — |
demo | swift run Demo |
doc | — |
pack | — |
publish | — |
publish:dry | — |
deno
Ecosystem: Deno (TypeScript/JavaScript)
| Command | Implementation |
|---|---|
clean | — |
restore | deno install |
build | — |
build:release | — |
test | deno test |
check | deno lint + deno check **/*.ts + deno fmt --check |
check:fix | deno fmt |
bench | deno bench |
demo | deno run demo.ts |
doc | deno doc |
pack | — |
publish | deno publish |
publish:dry | deno publish --dry-run |
| Command | Implementation |
|---|---|
clean | — |
restore | deno install |
build | — |
build:release | — |
test | deno test |
test:coverage | — |
check | deno lint + deno check **/*.ts + deno fmt --check |
check:fix | deno fmt |
bench | deno bench |
demo | deno run demo.ts |
doc | deno doc |
pack | — |
publish | deno publish |
publish:dry | deno publish --dry-run |
r
Ecosystem: R
| Command | Implementation |
|---|---|
clean | rm -rf *.tar.gz *.Rcheck/ |
restore | — |
build | R CMD build . |
build:release | — |
test | Rscript -e "devtools::test()" |
check | Rscript -e "lintr::lint_package()" + Rscript -e "styler::style_pkg(dry='on')" |
check:fix | Rscript -e "styler::style_pkg()" |
bench | — |
demo | Rscript demo.R |
doc | Rscript -e "roxygen2::roxygenise()" |
pack | R CMD build . |
publish | Rscript -e "devtools::release()" |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | rm -rf *.tar.gz *.Rcheck/ |
restore | — |
build | R CMD build . |
test | Rscript -e "devtools::test()" |
check | Rscript -e "lintr::lint_package()" + Rscript -e "styler::style_pkg(dry='on')" |
check:fix | Rscript -e "styler::style_pkg()" |
bench | — |
demo | Rscript demo.R |
doc | Rscript -e "roxygen2::roxygenise()" |
pack | R CMD build . |
publish | Rscript -e "devtools::release()" |
publish:dry | — |
- Note: Requires
devtools,lintr,styler, androxygen2packages
bundler
Ecosystem: Ruby (Bundler)
| Command | Implementation |
|---|---|
clean | bundle clean |
restore | bundle install |
build | bundle exec rake build |
build:release | — |
test | bundle exec rake test |
check | bundle exec rubocop |
check:fix | bundle exec rubocop -a |
bench | — |
demo | bundle exec ruby demo.rb |
doc | bundle exec yard doc |
pack | gem build *.gemspec |
publish | gem push *.gem |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | bundle clean |
restore | bundle install |
build | bundle exec rake build |
test | bundle exec rake test |
check | bundle exec rubocop |
check:fix | bundle exec rubocop -a |
bench | — |
demo | bundle exec ruby demo.rb |
doc | bundle exec yard doc |
pack | gem build *.gemspec |
publish | gem push *.gem |
publish:dry | — |
composer
Ecosystem: PHP (Composer)
| Command | Implementation |
|---|---|
clean | — |
restore | composer install |
build | — |
build:release | — |
test | composer test |
check | composer run-script lint + composer run-script format:check |
check:fix | composer run-script format |
bench | — |
demo | php demo.php |
doc | — |
pack | — |
publish | — |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | — |
restore | composer install |
build | — |
build:release | — |
test | composer test |
test:coverage | — |
check | composer run-script lint + composer run-script format:check |
check:fix | composer run-script format |
bench | — |
demo | php demo.php |
doc | — |
pack | — |
publish | — |
publish:dry | — |
- Note: Assumes
composer.jsondefines corresponding scripts
mix
Ecosystem: Elixir (Mix)
| Command | Implementation |
|---|---|
clean | mix clean |
restore | mix deps.get |
build | mix compile |
build:release | — |
test | mix test |
check | mix credo + mix dialyzer + mix format --check-formatted |
check:fix | mix format |
bench | — |
demo | mix run demo.exs |
doc | mix docs |
pack | — |
publish | mix hex.publish |
publish:dry | mix hex.publish --dry-run |
| Command | Implementation |
|---|---|
clean | mix clean |
restore | mix deps.get |
build | mix compile |
test | mix test |
check | mix credo + mix dialyzer + mix format --check-formatted |
check:fix | mix format |
bench | — |
demo | mix run demo.exs |
doc | mix docs |
publish | mix hex.publish |
publish:dry | mix hex.publish --dry-run |
sbt
Ecosystem: Scala (sbt)
| Command | Implementation |
|---|---|
clean | sbt clean |
restore | sbt update |
build | sbt compile |
build:release | — |
test | sbt test |
check | sbt scalafmtCheck |
check:fix | sbt scalafmt |
bench | — |
demo | sbt run |
doc | sbt doc |
pack | sbt package |
publish | sbt publish |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | sbt clean |
restore | sbt update |
build | sbt compile |
test | sbt test |
check | sbt scalafmtCheck |
check:fix | sbt scalafmt |
bench | — |
demo | sbt run |
doc | sbt doc |
pack | sbt package |
publish | sbt publish |
publish:dry | — |
cabal
Ecosystem: Haskell (Cabal)
| Command | Implementation |
|---|---|
clean | cabal clean |
restore | cabal update |
build | cabal build |
build:release | — |
test | cabal test |
check | cabal check + hlint . + ormolu --mode check $(find . -name '*.hs') |
check:fix | ormolu --mode inplace $(find . -name '*.hs') |
bench | cabal bench |
demo | cabal run |
doc | cabal haddock |
pack | — |
publish | cabal upload |
publish:dry | cabal upload --candidate |
| Command | Implementation |
|---|---|
clean | cabal clean |
restore | cabal update |
build | cabal build |
test | cabal test |
check | cabal check + hlint . + ormolu --mode check $(find . -name '*.hs') |
check:fix | ormolu --mode inplace $(find . -name '*.hs') |
bench | cabal bench |
demo | cabal run |
doc | cabal haddock |
publish | cabal upload |
publish:dry | cabal upload --candidate |
- Note:
lintrequireshlint,formatrequiresormolu
stack
Ecosystem: Haskell (Stack)
| Command | Implementation |
|---|---|
clean | stack clean |
restore | stack setup |
build | stack build |
build:release | — |
test | stack test |
check | stack exec -- hlint . + stack exec -- ormolu --mode check $(find . -name '*.hs') |
check:fix | stack exec -- ormolu --mode inplace $(find . -name '*.hs') |
bench | stack bench |
demo | stack run |
doc | stack haddock |
pack | — |
publish | stack upload |
publish:dry | stack upload --candidate |
| Command | Implementation |
|---|---|
clean | stack clean |
restore | stack setup |
build | stack build |
test | stack test |
check | stack exec -- hlint . + stack exec -- ormolu --mode check $(find . -name '*.hs') |
check:fix | stack exec -- ormolu --mode inplace $(find . -name '*.hs') |
bench | stack bench |
demo | stack run |
doc | stack haddock |
publish | stack upload |
publish:dry | stack upload --candidate |
dune
Ecosystem: OCaml (Dune)
| Command | Implementation |
|---|---|
clean | dune clean |
restore | opam install . --deps-only |
build | dune build |
build:release | — |
test | dune runtest |
check | dune fmt --preview |
check:fix | dune fmt |
bench | — |
demo | dune exec demo |
doc | dune build @doc |
pack | — |
publish | opam publish |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | dune clean |
restore | opam install . --deps-only |
build | dune build |
test | dune runtest |
check | dune fmt --preview |
check:fix | dune fmt |
bench | — |
demo | dune exec demo |
doc | dune build @doc |
publish | opam publish |
publish:dry | — |
lein
Ecosystem: Clojure (Leiningen)
| Command | Implementation |
|---|---|
clean | lein clean |
restore | lein deps |
build | lein compile |
build:release | — |
test | lein test |
check | lein check + lein eastwood + lein cljfmt check |
check:fix | lein cljfmt fix |
bench | — |
demo | lein run |
doc | lein codox |
pack | lein jar |
publish | lein deploy clojars |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | lein clean |
restore | lein deps |
build | lein compile |
test | lein test |
check | lein check + lein eastwood + lein cljfmt check |
check:fix | lein cljfmt fix |
bench | — |
demo | lein run |
doc | lein codox |
pack | lein jar |
publish | lein deploy clojars |
publish:dry | — |
- Note:
lintrequireseastwood,formatrequirescljfmt,docrequirescodox
zig
Ecosystem: Zig
| Command | Implementation |
|---|---|
clean | — |
restore | — |
build | zig build |
build:release | zig build -Doptimize=ReleaseFast |
test | zig build test |
check | zig fmt --check . |
check:fix | zig fmt . |
bench | — |
demo | zig build run |
doc | — |
pack | — |
publish | — |
publish:dry | — |
| Command | Implementation |
|---|---|
clean | — |
restore | — |
build | zig build |
build:release | zig build -Doptimize=ReleaseFast |
test | zig build test |
check | zig fmt --check . |
check:fix | zig fmt . |
bench | — |
demo | zig build run |
publish | — |
publish:dry | — |
rebar3
Ecosystem: Erlang (Rebar3)
| Command | Implementation |
|---|---|
clean | rebar3 clean |
restore | rebar3 get-deps |
build | rebar3 compile |
build:release | — |
test | rebar3 eunit |
check | rebar3 dialyzer + rebar3 lint |
check:fix | rebar3 format |
bench | — |
demo | rebar3 shell |
doc | rebar3 edoc |
pack | rebar3 tar |
publish | rebar3 hex publish |
publish:dry | rebar3 hex publish --dry-run |
| Command | Implementation |
|---|---|
clean | rebar3 clean |
restore | rebar3 get-deps |
build | rebar3 compile |
test | rebar3 eunit |
check | rebar3 dialyzer + rebar3 lint |
check:fix | rebar3 format |
bench | — |
demo | rebar3 shell |
doc | rebar3 edoc |
pack | rebar3 tar |
publish | rebar3 hex publish |
publish:dry | rebar3 hex publish --dry-run |
Custom Toolchains
Define custom toolchains in .structyl/config.json:
{
"toolchains": {
"my-toolchain": {
"version": "1.0.0",
"commands": {
"build": "custom-build-tool compile",
"build:release": "custom-build-tool compile --optimize",
"test": "custom-build-tool test",
"clean": "rm -rf out/"
}
}
},
"targets": {
"custom": {
"toolchain": "my-toolchain"
}
}
}Extending Built-in Toolchains
{
"toolchains": {
"cargo-workspace": {
"extends": "cargo",
"commands": {
"build": "cargo build --workspace",
"test": "cargo test --workspace"
}
}
}
}The extends field inherits all commands from the base toolchain, with specified commands overridden.
Toolchain Version Resolution
When Structyl generates mise.toml, it determines tool versions using this precedence (highest to lowest):
target.toolchain_version— Per-target override in target configurationtoolchains[name].version— Custom toolchain version in toolchains section- Built-in toolchain default — Version defined in the built-in toolchain preset
"latest"— Fallback when no version is specified
Example:
{
"targets": {
"rs": {
"toolchain": "cargo",
"toolchain_version": "1.80.0" // Takes precedence
}
},
"toolchains": {
"cargo": {
"version": "1.79.0" // Overridden by target
}
}
}In this example, the rs target uses Rust 1.80.0 (from toolchain_version), not 1.79.0.
Maintenance
Toolchain count maintenance: When adding or removing built-in toolchains, update the count in:
README.mdfeature descriptiondocs/index.mdfeatures sectionAGENTS.mdtoolchain system section- This document's Overview section