Guide for moving a Stack project to hx.
Overview
Stack and hx serve similar purposes but with different approaches:
| Aspect | Stack | hx |
|---|---|---|
| Toolchain | Bundles GHC | Uses GHCup/ghcup |
| Resolver | LTS/Nightly | GHC version + lockfile |
| Config | stack.yaml | hx.toml |
| Lock | stack.yaml.lock | hx.lock |
Quick Migration
cd my-stack-project
# Initialize hx
hx init --detect
# Generate lockfile
hx lock
# Build
hx build
# Test
hx testStep-by-Step Migration
1. Analyze Your Stack Project
Check your stack.yaml:
resolver: lts-22.0
packages:
- .
extra-deps:
- some-package-1.0.0Note:
- Resolver version
- Extra dependencies
- Any special configuration
2. Initialize hx
hx init --detecthx will:
- Read your
stack.yaml - Determine the GHC version from the resolver
- Create
hx.toml
3. Review hx.toml
The generated hx.toml:
[project]
name = "my-project"
version = "0.1.0"
[toolchain]
ghc = "9.6.5" # From LTS-22.0
[build]
ghc-options = ["-Wall"]4. Handle Extra Dependencies
Stack’s extra-deps need to be handled:
Option A: Add to .cabal file
If available on Hackage, add directly:
build-depends:
, some-package ^>=1.0Option B: Add as source dependency
For packages not on Hackage, add to cabal.project:
source-repository-package
type: git
location: https://github.com/user/some-package
tag: v1.0.05. Generate Lockfile
hx lockThis creates hx.lock with pinned versions.
6. Verify Build
hx build
hx test7. Clean Up (Optional)
After migration is complete:
# Remove Stack files (optional)
rm stack.yaml stack.yaml.lock
# Keep .cabal file - it's still neededResolver Mapping
Common Stack resolvers and their GHC versions:
| Resolver | GHC Version |
|---|---|
| lts-22.0 | 9.6.4 |
| lts-21.0 | 9.4.7 |
| lts-20.0 | 9.2.8 |
| nightly-2024-01-01 | 9.8.1 |
Find the GHC version for any resolver:
# Check resolver's GHC version
curl -s https://www.stackage.org/lts-22.0 | grep ghc-versionHandling Stack Features
Stack Scripts
Stack’s script interpreter:
#!/usr/bin/env stack
-- stack script --resolver lts-22.0
main = putStrLn "Hello"Use GHC directly or create a minimal project instead.
Custom Snapshots
If using custom snapshots, add dependencies to cabal.project:
source-repository-package
type: git
location: https://github.com/user/custom-package
tag: v1.0.0Package Flags
Stack’s flags:
flags:
some-package:
some-flag: trueConvert to cabal.project:
package some-package
flags: +some-flagExtra Include/Lib Dirs
Stack’s extra-include-dirs:
extra-include-dirs:
- /usr/local/include
extra-lib-dirs:
- /usr/local/libConvert to cabal.project:
package *
extra-include-dirs: /usr/local/include
extra-lib-dirs: /usr/local/libSide-by-Side Usage
You can use Stack and hx in the same project:
# Build with Stack
stack build
# Build with hx
hx buildBoth read from the same .cabal file.
Comparison
Commands
| Stack | hx |
|---|---|
stack build | hx build |
stack test | hx test |
stack run | hx run |
stack ghci | hx repl |
stack clean | hx clean |
stack setup | hx toolchain install |
Files
| Stack | hx |
|---|---|
stack.yaml | hx.toml |
stack.yaml.lock | hx.lock |
.stack-work/ | dist-newstyle/ |
Troubleshooting
Resolver Not Found
error: Unknown resolver: lts-22.0Specify GHC version explicitly:
hx init --ghc 9.6.5Missing Dependencies
If build fails with missing packages:
# Check what's needed
hx build 2>&1 | grep "unknown package"
# Add missing packages
hx add missing-packageGHC Version Mismatch
Stack and hx may use different GHC versions:
# See Stack's GHC
stack ghc -- --version
# See hx's GHC
hx toolchain list
# Install matching version
hx toolchain install --ghc 9.6.5Benefits of Migration
After migrating to hx:
- Unified tooling — Same GHC used for all tools
- Faster builds — Better caching in some scenarios
- Modern lockfile — TOML format with checksums
- BHC support — Alternative compiler backend
- Better diagnostics — Improved error messages
See Also
- hx init — Initialize hx
- hx lock — Generate lockfile
- Configuration — hx.toml reference