Complete reference for the hx.toml configuration file.
Overview
hx.toml is the main configuration file for hx projects. It uses the TOML format and lives in your project root.
[project]
Project metadata.
[project]
name = "my-project" # Package name
version = "0.1.0" # Package version
description = "My library" # Short description
license = "MIT" # SPDX license identifier
authors = ["Your Name <you@example.com>"]
repository = "https://github.com/user/project"
homepage = "https://project.example.com"Fields
| Field | Type | Description |
|---|---|---|
name | string | Package name (must match .cabal) |
version | string | Semantic version |
description | string | Short description |
license | string | SPDX license identifier |
authors | array | List of authors |
repository | string | Repository URL |
homepage | string | Project homepage URL |
[toolchain]
Toolchain version pinning.
[toolchain]
ghc = "9.8.2" # GHC version
cabal = "3.10.3.0" # Cabal version (optional)
resolver = "lts-22.0" # Stackage resolver (optional)Fields
| Field | Type | Description |
|---|---|---|
ghc | string | Required GHC version |
cabal | string | Required Cabal version |
resolver | string | Stackage resolver name |
Examples
# Pin exact GHC version
[toolchain]
ghc = "9.8.2"
# Pin both GHC and Cabal
[toolchain]
ghc = "9.8.2"
cabal = "3.10.3.0"
# Use Stackage resolver
[toolchain]
resolver = "lts-22.0"[compiler]
Compiler backend configuration.
[compiler]
backend = "ghc" # "ghc" or "bhc"
version = "9.8.2" # Compiler version (overrides toolchain)Fields
| Field | Type | Description |
|---|---|---|
backend | string | Compiler backend: "ghc" (default) or "bhc" |
version | string | Compiler version |
[compiler.ghc]
GHC-specific configuration.
[compiler.ghc]
version = "9.8.2" # GHC version
options = ["-Wall"] # Default GHC options[compiler.bhc]
BHC (Basel Haskell Compiler) configuration.
[compiler.bhc]
profile = "numeric" # "default", "server", "numeric", "edge"
emit_kernel_report = false # Generate kernel optimization report
tensor_fusion = false # Enable tensor fusion optimization
target = "aarch64-linux-gnu" # Cross-compilation targetBHC Profiles
| Profile | Description |
|---|---|
default | Balanced for general use |
server | Optimized for server workloads |
numeric | Optimized for numerical computation |
edge | Optimized for edge/embedded devices |
Examples
# Use GHC (default)
[compiler]
backend = "ghc"
# Use BHC with numeric optimizations
[compiler]
backend = "bhc"
[compiler.bhc]
profile = "numeric"
tensor_fusion = true[bhc-platform]
BHC Platform curated snapshot configuration. This is the BHC equivalent of Stackage — a curated set of packages verified to build together under BHC.
[bhc-platform]
snapshot = "bhc-platform-2026.1" # Curated package set
allow_newer = false # Allow packages outside the snapshot
extra_deps = {} # Override specific package versionsFields
| Field | Type | Default | Description |
|---|---|---|---|
snapshot | string | none | BHC Platform snapshot identifier |
allow_newer | bool | false | Allow packages from Hackage outside the snapshot |
extra_deps | table | {} | Override specific package versions |
Examples
# Use a BHC Platform snapshot
[compiler]
backend = "bhc"
[bhc-platform]
snapshot = "bhc-platform-2026.1"
# With overrides
[bhc-platform]
snapshot = "bhc-platform-2026.1"
allow_newer = true
extra_deps = { my-custom-lib = "1.0.0" }Note: BHC Platform snapshots are only applied when
[compiler].backend = "bhc". For GHC projects, use Stackage snapshots via[toolchain].resolver.
See hx bhc-platform for CLI commands.
[build]
Build configuration.
[build]
release = false # Build with optimizations by default
jobs = 4 # Parallel jobs (0 = auto)
ghc-options = ["-Wall", "-Wextra"]
split-sections = false # Enable split sections (smaller binaries)
incremental = true # Enable incremental buildsFields
| Field | Type | Default | Description |
|---|---|---|---|
release | bool | false | Build with optimizations |
jobs | int | CPU count | Parallel compilation jobs |
ghc-options | array | [] | Options passed to GHC |
split-sections | bool | false | Enable -split-sections |
incremental | bool | true | Enable incremental builds |
Examples
# Development defaults
[build]
release = false
ghc-options = ["-Wall", "-Wcompat"]
# Production build
[build]
release = true
ghc-options = ["-Wall", "-Werror", "-O2"]
split-sections = true
# Fast iteration
[build]
jobs = 0
incremental = true[test]
Test configuration.
[test]
default-suite = "unit-tests" # Default test suite to run
fail-fast = false # Stop on first failure
show-timing = true # Show test timing
coverage = false # Generate coverage reportFields
| Field | Type | Default | Description |
|---|---|---|---|
default-suite | string | all | Default test suite |
fail-fast | bool | false | Stop on first failure |
show-timing | bool | true | Display timing info |
coverage | bool | false | Generate coverage |
[test.coverage]
Coverage configuration.
[test.coverage]
enabled = false
output-dir = "coverage"
exclude = ["generated/**"][bench]
Benchmark configuration.
[bench]
default-suite = "criterion" # Default benchmark suite
release = true # Always build with optimizationsFields
| Field | Type | Default | Description |
|---|---|---|---|
default-suite | string | all | Default benchmark suite |
release | bool | true | Build with optimizations |
[run]
Run configuration.
[run]
default-exe = "my-app" # Default executable
args = [] # Default argumentsFields
| Field | Type | Default | Description |
|---|---|---|---|
default-exe | string | auto | Default executable to run |
args | array | [] | Default program arguments |
[repl]
REPL configuration.
[repl]
default = "lib" # Default component: lib, exe:name, test:name
auto-load = ["MyProject"] # Modules to load on start
ghci-options = ["-XOverloadedStrings"]
ghci-conf = ".ghci" # Custom .ghci fileFields
| Field | Type | Default | Description |
|---|---|---|---|
default | string | "lib" | Default component to load |
auto-load | array | [] | Modules to import |
ghci-options | array | [] | GHCi options |
ghci-conf | string | .ghci | GHCi config file |
[doc]
Documentation configuration.
[doc]
internal = false # Include internal modules
haddock-options = ["--hyperlinked-source"]
output-dir = "docs" # Output directoryFields
| Field | Type | Default | Description |
|---|---|---|---|
internal | bool | false | Document internal modules |
haddock-options | array | [] | Haddock options |
output-dir | string | default | Documentation output |
[fmt]
Code formatting configuration.
[fmt]
formatter = "ormolu" # "ormolu", "fourmolu", "stylish"
check = false # Check only, don't modify
exclude = ["generated/**"] # Patterns to excludeFields
| Field | Type | Default | Description |
|---|---|---|---|
formatter | string | "ormolu" | Formatter to use |
check | bool | false | Check-only mode |
exclude | array | [] | Excluded patterns |
[lint]
Linter configuration.
[lint]
extra-hints = [".hlint.yaml"] # Additional hint files
ignore = ["Eta reduce"] # Ignored hintsFields
| Field | Type | Default | Description |
|---|---|---|---|
extra-hints | array | [] | Additional hint files |
ignore | array | [] | Ignored hints |
[watch]
Watch mode configuration.
[watch]
clear = true # Clear terminal on rebuild
debounce = 300 # Debounce delay (ms)
include = ["config/**"] # Additional patterns to watch
exclude = ["dist-newstyle/**"] # Patterns to excludeFields
| Field | Type | Default | Description |
|---|---|---|---|
clear | bool | false | Clear terminal |
debounce | int | 300 | Debounce delay in ms |
include | array | [] | Additional watch patterns |
exclude | array | [] | Excluded patterns |
[dependencies]
Dependency management configuration.
[dependencies]
lock-strategy = "hx" # "hx" or "cabal-freeze"
index-state = "2024-01-15T00:00:00Z"Fields
| Field | Type | Default | Description |
|---|---|---|---|
lock-strategy | string | "hx" | Lockfile strategy |
index-state | string | none | Hackage index state |
Complete Example
[project]
name = "my-app"
version = "1.0.0"
description = "My awesome Haskell application"
license = "MIT"
authors = ["Developer <dev@example.com>"]
repository = "https://github.com/example/my-app"
[toolchain]
ghc = "9.8.2"
cabal = "3.10.3.0"
[compiler]
backend = "ghc"
[compiler.ghc]
options = ["-Wall", "-Wextra", "-Wcompat"]
[build]
release = false
jobs = 4
split-sections = true
[test]
fail-fast = true
show-timing = true
[test.coverage]
enabled = true
output-dir = "coverage"
[run]
default-exe = "my-app"
args = ["--verbose"]
[repl]
auto-load = ["MyApp", "MyApp.Config"]
ghci-options = ["-XOverloadedStrings"]
[fmt]
formatter = "fourmolu"
exclude = ["generated/**"]
[lint]
ignore = ["Use camelCase"]
[watch]
clear = true
debounce = 200
exclude = [".git/**", "dist-newstyle/**"]
[dependencies]
lock-strategy = "hx"Complete BHC Example
[project]
name = "ml-pipeline"
version = "0.1.0"
[compiler]
backend = "bhc"
[compiler.bhc]
profile = "numeric"
tensor_fusion = true
[bhc-platform]
snapshot = "bhc-platform-2026.1"
[build]
release = true
[test]
fail-fast = true