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