Haskell · build · tooling
Stack vs Cabal: choosing a Haskell build tool
Once you have a Haskell compiler installed, you need a way to manage dependencies and build your project. In 2026 there are two mainstream choices: Cabal and Stack. They do the same core job — fetch libraries, build your code, run tests — but make different trade-offs around where packages come from and how reproducible builds are. This guide explains what each one is, how they differ, the equivalent commands, and how to choose.
What Cabal is
Cabal is Haskell's original build system. The word covers two things: the Cabal library/specification (the .cabal file format that describes a package) and cabal-install, the cabal command-line tool that builds packages and resolves dependencies. By default it pulls libraries from Hackage, the central Haskell package archive.
Modern Cabal uses nix-style local builds (the old v2- commands, now the default), which give each project an isolated build and a shared global store of built packages. A dependency solver picks versions that satisfy the bounds you declare:
-- in your .cabal file
build-depends: base >=4.14 && <5, text, aeson ^>=2.1 The ^>= caret operator means "at least this version, but allow only compatible later ones." Project-wide settings live in a cabal.project file. This is the toolchain most closely aligned with GHC and Hackage releases.
What Stack is
Stack is a build tool built around reproducibility. Instead of solving versions against all of Hackage, it builds against a Stackage snapshot: a curated set of package versions that are known to compile together. You pin a snapshot in stack.yaml:
resolver: lts-22.14
packages:
- . Because the snapshot fixes every version, anyone who checks out your project and runs stack build gets the same dependency versions — and Stack will install the matching GHC for that snapshot automatically. That "it just works the same everywhere" guarantee is Stack's main appeal, especially for teams and CI.
The key differences
- Package source — Cabal resolves against all of Hackage; Stack builds against a curated Stackage snapshot. Stackage trades some freshness for guaranteed-compatible sets.
- Reproducibility — Stack pins everything via the snapshot by default. Cabal can be equally reproducible with a
cabal.project.freezefile, but you opt into it. - GHC management — Stack downloads and manages the GHC version a snapshot needs. With Cabal, you bring your own GHC (commonly installed via GHCup).
- Config files — both read the package's
.cabalfile. Stack addsstack.yaml; Cabal addscabal.project. - Ecosystem alignment — Cabal tracks GHC and Hackage releases closely; Stack moves at the pace of snapshot curation.
The equivalent commands
Day to day, the two feel similar:
-- Cabal -- Stack
cabal build stack build
cabal run myapp stack run
cabal test stack test
cabal repl stack ghci
cabal haddock stack haddock Both drive the same compiler underneath — see the GHC guide for the flags that matter. Note that today's Cabal descends from the workflow introduced in Cabal 2.0, which replaced the older sandbox approach.
Which should you choose?
In 2026, both are good and actively maintained — this is not a case where one is obsolete. A reasonable rule of thumb:
- Pick Cabal if you want the default, GHC-aligned toolchain, the latest package versions from Hackage, and fine-grained control over version bounds. It's the path most new tutorials assume.
- Pick Stack if you value out-of-the-box reproducibility and automatic GHC management, or you're on a team where "everyone gets the same build" matters more than having the newest library versions.
You don't have to decide forever: GHCup installs both, and many projects ship a stack.yaml and a cabal.project so contributors can use either. Try one, and switch if its trade-offs don't fit.
FAQ
Is Cabal or Stack better? Neither is strictly better; they optimise for different things. Cabal favours up-to-date Hackage versions and close GHC alignment; Stack favours curated, reproducible snapshots and automatic GHC installs.
Do Stack and Cabal use the same package format? Yes. Both read the package's .cabal file. Stack layers stack.yaml on top; Cabal layers cabal.project.
What is a Stackage snapshot? A curated set of Hackage package versions verified to build together, identified by a resolver like lts-22.14. Pinning one makes builds reproducible.
Can I switch from Stack to Cabal later? Usually yes — the .cabal file is shared, so you mainly add a cabal.project and provide a GHC (via GHCup). Version bounds may need a little tidying.
New to the toolchain? Start by installing Haskell with GHCup, which sets up GHC, Cabal and Stack together.
Build Haskell faster
Both Stack and Cabal compile faster with more cores and RAM than a laptop — handy for large projects and CI. Infomaniak, a Swiss, privacy-respecting host, offers VPS and cloud servers for builds.
See Infomaniak cloud →Affiliate link — supports these free guides.