Skip to content

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:

json
{
  "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:

FileToolchain
Cargo.tomlcargo
go.modgo
deno.jsonc, deno.jsondeno
pnpm-lock.yamlpnpm
yarn.lockyarn
bun.lockbbun
package.jsonnpm
uv.lockuv
poetry.lockpoetry
pyproject.toml, setup.pypython
build.gradle.kts, build.gradlegradle
pom.xmlmaven
build.sbtsbt
Package.swiftswift
CMakeLists.txtcmake
Makefilemake
*.sln, Directory.Build.props, global.jsondotnet
*.csproj, *.fsprojdotnet
Gemfilebundler
composer.jsoncomposer
mix.exsmix
stack.yamlstack
*.cabalcabal
dune-projectdune
project.cljlein
build.zigzig
rebar.configrebar3
DESCRIPTIONr

Detection Algorithm ​

  1. For each marker pattern in the table above (checked in listed order):
  2. If the pattern contains * (glob): check if any files match the glob in the target directory
  3. Otherwise: check if the exact file exists in the target directory
  4. Return the toolchain for the first match found
  5. If no patterns match, the toolchain is undefined (requires explicit toolchain configuration)

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:

CommandPurpose
cleanClean build artifacts
restoreRestore/install dependencies
buildBuild targets
build:releaseBuild targets (release mode)†
testRun tests
test:coverageRun tests with coverage (optional, see ‡)
checkRun static analysis (lint, typecheck, format-check)*
check:fixAuto-fix static analysis issues
benchRun benchmarks
demoRun demos
docGenerate documentation
packCreate package
publishPublish package to registry
publish:dryDry-run publish (validate without uploading)
CommandPurpose
cleanClean build artifacts
restoreRestore/install dependencies
buildBuild targets
build:releaseBuild targets (release mode)
testRun tests
test:coverageRun tests with coverage
checkRun static analysis (lint, typecheck, format-check)
check:fixAuto-fix static analysis issues
benchRun benchmarks
demoRun demos
docGenerate documentation
packCreate package
publishPublish package to registry
publish:dryDry-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. The restore command 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, and bench depend on ecosystem support. See individual toolchain sections (e.g., Cargo, Go) for exact command mappings. Unavailable commands are set to null (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 to null in configuration). Invoking a null command succeeds with a warning: command "X" is not available.

ToolchainLintTypecheckFormat-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:coverage command (marked with ‡ in the vocabulary table) is intentionally omitted from this composition table. No built-in toolchain provides test:coverage—projects MUST define custom implementations using language-specific coverage tools (e.g., cargo-tarpaulin, go test -cover, coverage.py).

Note: For check:fix compositions (auto-fix behavior), see the summary table below. Most toolchains run format commands as part of check:fix, with some also including lint auto-fix.

check:fix Composition Summary ​

ToolchainAuto-fix Components
cargocargo fmt
dotnetdotnet format
gogo fmt ./...
npmnpm run lint -- --fix + npm run format
pnpmpnpm lint --fix + pnpm format
yarnyarn lint --fix + yarn format
bunbun run lint --fix + bun run format
pythonruff check --fix . + ruff format .
uvuv run ruff check --fix . + uv run ruff format .
poetrypoetry run ruff check --fix . + poetry run ruff format .
gradlegradle spotlessApply
mavenmvn spotless:apply
makemake fix
cmakecmake --build build --target format
swiftswiftlint --fix + swiftformat .
denodeno fmt
rRscript -e "styler::style_pkg()"
bundlerbundle exec rubocop -a
composercomposer run-script format
mixmix format
sbtsbt scalafmt
cabalormolu --mode inplace $(find . -name '*.hs')
stackstack exec -- ormolu --mode inplace $(find . -name '*.hs')
dunedune fmt
leinlein cljfmt fix
zigzig fmt .
rebar3rebar3 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. For check: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 --fix in a check:fix composition fails, the format step is skipped.


Built-in Toolchains ​

cargo ​

Ecosystem: Rust

CommandImplementation
cleancargo clean
restore—
buildcargo build
build:releasecargo build --release
testcargo test
checkcargo clippy -- -D warnings + cargo fmt --check
check:fixcargo fmt
benchcargo bench
democargo run --example demo
doccargo doc --no-deps
packcargo package
publishcargo publish
publish:drycargo publish --dry-run
CommandImplementation
cleancargo clean
restore—
buildcargo build
build:releasecargo build --release
testcargo test
checkcargo clippy -- -D warnings + cargo fmt --check
check:fixcargo fmt
benchcargo bench
democargo run --example demo
doccargo doc --no-deps
packcargo package
publishcargo publish
publish:drycargo publish --dry-run

dotnet ​

Ecosystem: .NET (C#, F#, VB)

CommandImplementation
cleandotnet clean
restoredotnet restore
builddotnet build
build:releasedotnet build -c Release
testdotnet test
checkdotnet format --verify-no-changes
check:fixdotnet format
bench—
demodotnet run --project Demo
doc—
packdotnet pack
publishdotnet nuget push
publish:dry—
CommandImplementation
cleandotnet clean
restoredotnet restore
builddotnet build
build:releasedotnet build -c Release
testdotnet test
checkdotnet format --verify-no-changes
check:fixdotnet format
bench—
demodotnet run --project Demo
doc—
packdotnet pack
publishdotnet nuget push
publish:dry—

go ​

Ecosystem: Go

CommandImplementation
cleango clean
restorego mod download
buildgo build ./...
build:release—
testgo test ./...
checkgolangci-lint run + go vet ./... + test -z "$(gofmt -l .)"
check:fixgo fmt ./...
benchgo test -bench=. ./...
demogo run ./cmd/demo
docgo doc ./...
pack—
publish—
publish:dry—
CommandImplementation
cleango clean
restorego mod download
buildgo build ./...
testgo test ./...
checkgolangci-lint run + go vet ./... + test -z "$(gofmt -l .)"
check:fixgo fmt ./...
benchgo test -bench=. ./...
demogo run ./cmd/demo
docgo doc ./...
pack—
publish—
publish:dry—
  • Note: lint requires golangci-lint to be installed
  • Note: Go does not have a distinct release build mode. Use -ldflags or build tags for production builds.

Note for Node.js toolchains (npm, pnpm, yarn, bun): Commands like clean, lint, typecheck, and format assume corresponding scripts are defined in package.json. Missing scripts result in skip errors.

npm ​

Ecosystem: Node.js (npm)

CommandImplementation
cleannpm run clean
restorenpm ci
buildnpm run build
build:release—
testnpm test
checknpm run lint + npm run typecheck + npm run format:check
check:fixnpm run lint -- --fix + npm run format
bench—
demonpm run demo
doc—
packnpm pack
publishnpm publish
publish:drynpm publish --dry-run
CommandImplementation
cleannpm run clean
restorenpm ci
buildnpm run build
testnpm test
checknpm run lint + npm run typecheck + npm run format:check
check:fixnpm run lint -- --fix + npm run format
bench—
demonpm run demo
doc—
packnpm pack
publishnpm publish
publish:drynpm publish --dry-run

pnpm ​

Ecosystem: Node.js (pnpm)

CommandImplementation
cleanpnpm run clean
restorepnpm install --frozen-lockfile
buildpnpm build
build:release—
testpnpm test
checkpnpm lint + pnpm typecheck + pnpm format:check
check:fixpnpm lint --fix + pnpm format
bench—
demopnpm run demo
doc—
packpnpm pack
publishpnpm publish
publish:drypnpm publish --dry-run
CommandImplementation
cleanpnpm run clean
restorepnpm install --frozen-lockfile
buildpnpm build
testpnpm test
checkpnpm lint + pnpm typecheck + pnpm format:check
check:fixpnpm lint --fix + pnpm format
bench—
demopnpm run demo
doc—
packpnpm pack
publishpnpm publish
publish:drypnpm publish --dry-run

yarn ​

Ecosystem: Node.js (Yarn)

CommandImplementation
cleanyarn clean
restoreyarn install --frozen-lockfile
buildyarn build
build:release—
testyarn test
checkyarn lint + yarn typecheck + yarn format:check
check:fixyarn lint --fix + yarn format
bench—
demoyarn run demo
doc—
packyarn pack
publishyarn npm publish
publish:dryyarn npm publish --dry-run
CommandImplementation
cleanyarn clean
restoreyarn install --frozen-lockfile
buildyarn build
testyarn test
checkyarn lint + yarn typecheck + yarn format:check
check:fixyarn lint --fix + yarn format
bench—
demoyarn run demo
doc—
packyarn pack
publishyarn npm publish
publish:dryyarn npm publish --dry-run

bun ​

Ecosystem: Bun

CommandImplementation
cleanbun run clean
restorebun install --frozen-lockfile
buildbun run build
build:release—
testbun test
checkbun run lint + bun run typecheck + bun run format:check
check:fixbun run lint --fix + bun run format
bench—
demobun run demo
doc—
packbun pm pack
publishbun publish
publish:drybun publish --dry-run
CommandImplementation
cleanbun run clean
restorebun install --frozen-lockfile
buildbun run build
testbun test
checkbun run lint + bun run typecheck + bun run format:check
check:fixbun run lint --fix + bun run format
bench—
demobun run demo
doc—
packbun pm pack
publishbun publish
publish:drybun publish --dry-run

python ​

Ecosystem: Python (pip/setuptools)

CommandImplementation
cleanrm -rf dist/ build/ *.egg-info **/__pycache__/
restorepip install -e .
buildpython -m build
build:release—
testpytest
checkruff check . + mypy . + ruff format --check .
check:fixruff check --fix . + ruff format .
bench—
demopython demo.py
doc—
packpython -m build
publishtwine upload dist/*
publish:dry—
CommandImplementation
cleanrm -rf dist/ build/ *.egg-info **/__pycache__/
restorepip install -e .
buildpython -m build
testpytest
checkruff check . + mypy . + ruff format --check .
check:fixruff check --fix . + ruff format .
bench—
demopython demo.py
doc—
packpython -m build
publishtwine upload dist/*
publish:dry—
  • Note: Assumes ruff and mypy are installed

uv ​

Ecosystem: Python (uv)

CommandImplementation
cleanrm -rf dist/ build/ *.egg-info .venv/
restoreuv sync --all-extras
builduv build
build:release—
testuv run pytest
checkuv run ruff check . + uv run mypy . + uv run ruff format --check .
check:fixuv run ruff check --fix . + uv run ruff format .
bench—
demouv run python demo.py
doc—
packuv build
publishuv publish
publish:dry—
CommandImplementation
cleanrm -rf dist/ build/ *.egg-info .venv/
restoreuv sync --all-extras
builduv build
testuv run pytest
checkuv run ruff check . + uv run mypy . + uv run ruff format --check .
check:fixuv run ruff check --fix . + uv run ruff format .
bench—
demouv run python demo.py
doc—
packuv build
publishuv publish
publish:dry—

poetry ​

Ecosystem: Python (Poetry)

CommandImplementation
cleanrm -rf dist/
restorepoetry install
buildpoetry build
build:release—
testpoetry run pytest
checkpoetry run ruff check . + poetry run mypy . + poetry run ruff format --check .
check:fixpoetry run ruff check --fix . + poetry run ruff format .
bench—
demopoetry run python demo.py
doc—
packpoetry build
publishpoetry publish
publish:drypoetry publish --dry-run
CommandImplementation
cleanrm -rf dist/
restorepoetry install
buildpoetry build
testpoetry run pytest
checkpoetry run ruff check . + poetry run mypy . + poetry run ruff format --check .
check:fixpoetry run ruff check --fix . + poetry run ruff format .
bench—
demopoetry run python demo.py
doc—
packpoetry build
publishpoetry publish
publish:drypoetry publish --dry-run

gradle ​

Ecosystem: JVM (Gradle)

CommandImplementation
cleangradle clean
restore—
buildgradle build -x test
build:release—
testgradle test
checkgradle check -x test + gradle spotlessCheck
check:fixgradle spotlessApply
bench—
demogradle run
docgradle javadoc
packgradle jar
publishgradle publish
publish:dry—
CommandImplementation
cleangradle clean
restore—
buildgradle build -x test
testgradle test
checkgradle check -x test + gradle spotlessCheck
check:fixgradle spotlessApply
bench—
demogradle run
docgradle javadoc
packgradle jar
publishgradle publish
publish:dry—
  • Note: Use ./gradlew if wrapper present

maven ​

Ecosystem: JVM (Maven)

CommandImplementation
cleanmvn clean
restoremvn dependency:resolve
buildmvn compile
build:release—
testmvn test
checkmvn checkstyle:check + mvn spotless:check
check:fixmvn spotless:apply
bench—
demomvn exec:java
docmvn javadoc:javadoc
packmvn package -DskipTests
publishmvn deploy
publish:dry—
CommandImplementation
cleanmvn clean
restoremvn dependency:resolve
buildmvn compile
testmvn test
checkmvn checkstyle:check + mvn spotless:check
check:fixmvn spotless:apply
bench—
demomvn exec:java
docmvn javadoc:javadoc
packmvn package -DskipTests
publishmvn deploy
publish:dry—
  • Note: format and format-check require the Spotless Maven plugin

make ​

Ecosystem: Generic (Make)

CommandImplementation
cleanmake clean
restore—
buildmake
build:releasemake release
testmake test
checkmake check
check:fixmake fix
benchmake bench
demomake demo
docmake doc
packmake dist
publishmake publish
publish:drymake publish-dry
CommandImplementation
cleanmake clean
restore—
buildmake
build:releasemake release
testmake test
checkmake check
check:fixmake fix
benchmake bench
demomake demo
docmake doc
packmake dist
publishmake publish
publish:drymake publish-dry
  • Note: Assumes Makefile defines corresponding targets

cmake ​

Ecosystem: C/C++ (CMake)

CommandImplementation
cleancmake --build build --target clean
restorecmake -B build -S .
buildcmake --build build
build:release—
testctest --test-dir build
checkcmake --build build --target lint + cmake --build build --target format-check
check:fixcmake --build build --target format
bench—
democmake --build build --target demo && ./build/demo
doccmake --build build --target doc
packcmake --build build --target package
publish—
publish:dry—
CommandImplementation
cleancmake --build build --target clean
restorecmake -B build -S .
buildcmake --build build
testctest --test-dir build
checkcmake --build build --target lint + cmake --build build --target format-check
check:fixcmake --build build --target format
bench—
democmake --build build --target demo && ./build/demo
doccmake --build build --target doc
packcmake --build build --target package
publish—
publish:dry—
  • Note: lint, format, and format-check require corresponding CMake targets to be defined

swift ​

Ecosystem: Swift

CommandImplementation
cleanswift package clean
restoreswift package resolve
buildswift build
build:releaseswift build -c release
testswift test
checkswiftlint + swiftformat --lint .
check:fixswiftlint --fix + swiftformat .
bench—
demoswift run Demo
doc—
pack—
publish—
publish:dry—
CommandImplementation
cleanswift package clean
restoreswift package resolve
buildswift build
build:releaseswift build -c release
testswift test
checkswiftlint + swiftformat --lint .
check:fixswiftlint --fix + swiftformat .
bench—
demoswift run Demo
doc—
pack—
publish—
publish:dry—

deno ​

Ecosystem: Deno (TypeScript/JavaScript)

CommandImplementation
clean—
restoredeno install
build—
build:release—
testdeno test
checkdeno lint + deno check **/*.ts + deno fmt --check
check:fixdeno fmt
benchdeno bench
demodeno run demo.ts
docdeno doc
pack—
publishdeno publish
publish:drydeno publish --dry-run
CommandImplementation
clean—
restoredeno install
build—
build:release—
testdeno test
test:coverage—
checkdeno lint + deno check **/*.ts + deno fmt --check
check:fixdeno fmt
benchdeno bench
demodeno run demo.ts
docdeno doc
pack—
publishdeno publish
publish:drydeno publish --dry-run

r ​

Ecosystem: R

CommandImplementation
cleanrm -rf *.tar.gz *.Rcheck/
restore—
buildR CMD build .
build:release—
testRscript -e "devtools::test()"
checkRscript -e "lintr::lint_package()" + Rscript -e "styler::style_pkg(dry='on')"
check:fixRscript -e "styler::style_pkg()"
bench—
demoRscript demo.R
docRscript -e "roxygen2::roxygenise()"
packR CMD build .
publishRscript -e "devtools::release()"
publish:dry—
CommandImplementation
cleanrm -rf *.tar.gz *.Rcheck/
restore—
buildR CMD build .
testRscript -e "devtools::test()"
checkRscript -e "lintr::lint_package()" + Rscript -e "styler::style_pkg(dry='on')"
check:fixRscript -e "styler::style_pkg()"
bench—
demoRscript demo.R
docRscript -e "roxygen2::roxygenise()"
packR CMD build .
publishRscript -e "devtools::release()"
publish:dry—
  • Note: Requires devtools, lintr, styler, and roxygen2 packages

bundler ​

Ecosystem: Ruby (Bundler)

CommandImplementation
cleanbundle clean
restorebundle install
buildbundle exec rake build
build:release—
testbundle exec rake test
checkbundle exec rubocop
check:fixbundle exec rubocop -a
bench—
demobundle exec ruby demo.rb
docbundle exec yard doc
packgem build *.gemspec
publishgem push *.gem
publish:dry—
CommandImplementation
cleanbundle clean
restorebundle install
buildbundle exec rake build
testbundle exec rake test
checkbundle exec rubocop
check:fixbundle exec rubocop -a
bench—
demobundle exec ruby demo.rb
docbundle exec yard doc
packgem build *.gemspec
publishgem push *.gem
publish:dry—

composer ​

Ecosystem: PHP (Composer)

CommandImplementation
clean—
restorecomposer install
build—
build:release—
testcomposer test
checkcomposer run-script lint + composer run-script format:check
check:fixcomposer run-script format
bench—
demophp demo.php
doc—
pack—
publish—
publish:dry—
CommandImplementation
clean—
restorecomposer install
build—
build:release—
testcomposer test
test:coverage—
checkcomposer run-script lint + composer run-script format:check
check:fixcomposer run-script format
bench—
demophp demo.php
doc—
pack—
publish—
publish:dry—
  • Note: Assumes composer.json defines corresponding scripts

mix ​

Ecosystem: Elixir (Mix)

CommandImplementation
cleanmix clean
restoremix deps.get
buildmix compile
build:release—
testmix test
checkmix credo + mix dialyzer + mix format --check-formatted
check:fixmix format
bench—
demomix run demo.exs
docmix docs
pack—
publishmix hex.publish
publish:drymix hex.publish --dry-run
CommandImplementation
cleanmix clean
restoremix deps.get
buildmix compile
testmix test
checkmix credo + mix dialyzer + mix format --check-formatted
check:fixmix format
bench—
demomix run demo.exs
docmix docs
publishmix hex.publish
publish:drymix hex.publish --dry-run

sbt ​

Ecosystem: Scala (sbt)

CommandImplementation
cleansbt clean
restoresbt update
buildsbt compile
build:release—
testsbt test
checksbt scalafmtCheck
check:fixsbt scalafmt
bench—
demosbt run
docsbt doc
packsbt package
publishsbt publish
publish:dry—
CommandImplementation
cleansbt clean
restoresbt update
buildsbt compile
testsbt test
checksbt scalafmtCheck
check:fixsbt scalafmt
bench—
demosbt run
docsbt doc
packsbt package
publishsbt publish
publish:dry—

cabal ​

Ecosystem: Haskell (Cabal)

CommandImplementation
cleancabal clean
restorecabal update
buildcabal build
build:release—
testcabal test
checkcabal check + hlint . + ormolu --mode check $(find . -name '*.hs')
check:fixormolu --mode inplace $(find . -name '*.hs')
benchcabal bench
democabal run
doccabal haddock
pack—
publishcabal upload
publish:drycabal upload --candidate
CommandImplementation
cleancabal clean
restorecabal update
buildcabal build
testcabal test
checkcabal check + hlint . + ormolu --mode check $(find . -name '*.hs')
check:fixormolu --mode inplace $(find . -name '*.hs')
benchcabal bench
democabal run
doccabal haddock
publishcabal upload
publish:drycabal upload --candidate
  • Note: lint requires hlint, format requires ormolu

stack ​

Ecosystem: Haskell (Stack)

CommandImplementation
cleanstack clean
restorestack setup
buildstack build
build:release—
teststack test
checkstack exec -- hlint . + stack exec -- ormolu --mode check $(find . -name '*.hs')
check:fixstack exec -- ormolu --mode inplace $(find . -name '*.hs')
benchstack bench
demostack run
docstack haddock
pack—
publishstack upload
publish:drystack upload --candidate
CommandImplementation
cleanstack clean
restorestack setup
buildstack build
teststack test
checkstack exec -- hlint . + stack exec -- ormolu --mode check $(find . -name '*.hs')
check:fixstack exec -- ormolu --mode inplace $(find . -name '*.hs')
benchstack bench
demostack run
docstack haddock
publishstack upload
publish:drystack upload --candidate

dune ​

Ecosystem: OCaml (Dune)

CommandImplementation
cleandune clean
restoreopam install . --deps-only
builddune build
build:release—
testdune runtest
checkdune fmt --preview
check:fixdune fmt
bench—
demodune exec demo
docdune build @doc
pack—
publishopam publish
publish:dry—
CommandImplementation
cleandune clean
restoreopam install . --deps-only
builddune build
testdune runtest
checkdune fmt --preview
check:fixdune fmt
bench—
demodune exec demo
docdune build @doc
publishopam publish
publish:dry—

lein ​

Ecosystem: Clojure (Leiningen)

CommandImplementation
cleanlein clean
restorelein deps
buildlein compile
build:release—
testlein test
checklein check + lein eastwood + lein cljfmt check
check:fixlein cljfmt fix
bench—
demolein run
doclein codox
packlein jar
publishlein deploy clojars
publish:dry—
CommandImplementation
cleanlein clean
restorelein deps
buildlein compile
testlein test
checklein check + lein eastwood + lein cljfmt check
check:fixlein cljfmt fix
bench—
demolein run
doclein codox
packlein jar
publishlein deploy clojars
publish:dry—
  • Note: lint requires eastwood, format requires cljfmt, doc requires codox

zig ​

Ecosystem: Zig

CommandImplementation
clean—
restore—
buildzig build
build:releasezig build -Doptimize=ReleaseFast
testzig build test
checkzig fmt --check .
check:fixzig fmt .
bench—
demozig build run
doc—
pack—
publish—
publish:dry—
CommandImplementation
clean—
restore—
buildzig build
build:releasezig build -Doptimize=ReleaseFast
testzig build test
checkzig fmt --check .
check:fixzig fmt .
bench—
demozig build run
publish—
publish:dry—

rebar3 ​

Ecosystem: Erlang (Rebar3)

CommandImplementation
cleanrebar3 clean
restorerebar3 get-deps
buildrebar3 compile
build:release—
testrebar3 eunit
checkrebar3 dialyzer + rebar3 lint
check:fixrebar3 format
bench—
demorebar3 shell
docrebar3 edoc
packrebar3 tar
publishrebar3 hex publish
publish:dryrebar3 hex publish --dry-run
CommandImplementation
cleanrebar3 clean
restorerebar3 get-deps
buildrebar3 compile
testrebar3 eunit
checkrebar3 dialyzer + rebar3 lint
check:fixrebar3 format
bench—
demorebar3 shell
docrebar3 edoc
packrebar3 tar
publishrebar3 hex publish
publish:dryrebar3 hex publish --dry-run

Custom Toolchains ​

Define custom toolchains in .structyl/config.json:

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 ​

json
{
  "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):

  1. target.toolchain_version — Per-target override in target configuration
  2. toolchains[name].version — Custom toolchain version in toolchains section
  3. Built-in toolchain default — Version defined in the built-in toolchain preset
  4. "latest" — Fallback when no version is specified

Example:

json
{
  "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.md feature description
  • docs/index.md features section
  • AGENTS.md toolchain system section
  • This document's Overview section

© 2026 Andrey Akinshin MIT