Stack (Haskell)
By the Haskell Stack community (originally FP Complete)
Stack is a build tool and project manager for Haskell that manages compiler installation, dependency resolution, and reproducible builds by pinning projects to curated snapshots of mutually compatible package versions. It wraps GHC and…
Definition
Stack is a build tool and project manager for Haskell that manages compiler installation, dependency resolution, and reproducible builds by pinning projects to curated snapshots of mutually compatible package versions. It wraps GHC and Cabal-format packages behind a single command-line workflow aimed at making Haskell builds reproducible across machines without manual dependency version juggling or unexpected compiler mismatches across development teams.
Overview
Haskell's package ecosystem, centered on the Cabal package format and the Hackage repository, historically suffered from a problem sometimes called "Cabal hell," where independently version-constrained packages could combine into unsatisfiable or subtly incompatible dependency sets on a given machine. Stack was created specifically to solve this by changing the unit of dependency resolution from individual package version ranges to a curated snapshot, a large, pre-tested set of package versions known to build and work together. Mechanically, a Stack project's `stack.yaml` file specifies a resolver, typically a Stackage snapshot, which is a fixed, tested combination of GHC version and package versions maintained by the Stackage project. When Stack builds a project, it resolves dependencies against that snapshot rather than solving version constraints from scratch each time, which makes builds far more predictable across different developers' machines and over time. Stack also manages GHC installation itself, downloading and isolating specific GHC versions per project so a machine can have multiple Haskell projects each pinned to a different compiler version without conflict. Stack's snapshot-based approach contrasts with Cabal's own newer `cabal build` with dependency-solving and freeze files, which achieved broadly similar reproducibility goals through a different mechanism, version-range solving with a lockfile rather than curated snapshots; the two tools' capabilities have converged over time, and choosing between them today is often more about team convention and legacy project setup than a hard technical gap. Stack differs more sharply from Cargo or npm in that Haskell projects still ultimately depend on Cabal-format package metadata underneath Stack, so Stack is best understood as a layer that manages GHC versions and snapshot-pinned dependency resolution on top of the existing Cabal package format, not a wholesale replacement for it. In practice, developers use `stack new` to scaffold a project, `stack build` to compile it against the pinned snapshot, and `stack test` and `stack exec` for testing and running. Stack is particularly common in teams and tutorials that prioritize an out-of-the-box reproducible setup without needing to hand-pick compatible package versions, and its per-project GHC installation is valued in environments supporting several Haskell codebases on different compiler versions simultaneously. The trade-off is an extra layer of tooling and snapshot terminology on top of Cabal, and pinning to a curated snapshot can occasionally lag behind the very latest package releases on Hackage compared to solving dependencies directly against Hackage with Cabal. Teams that want the newest packages immediately, or who are comfortable managing Cabal's own freeze-file reproducibility, sometimes prefer plain Cabal instead.
Key Features
- Pins projects to curated Stackage snapshots of mutually compatible packages
- Manages installation of specific GHC compiler versions per project
- Wraps and builds on top of the existing Cabal package format
- Provides reproducible builds across different developer machines
- Supports stack new, build, test, and exec commands for a full workflow
- Isolates GHC and package versions so multiple projects can coexist
Use Cases
Alternatives
Frequently Asked Questions
From the Blog
Full-Stack Java Developer Roadmap 2026
Becoming a full stack Java developer in 2026 means mastering core Java, Spring Boot, SQL, and React in that order, over roughly six months.
Read More Projects & Case StudiesProject: Build a Full-Stack To-Do App with React, Node.js and MongoDB
A full-stack to-do app is the perfect first MERN project — it covers every concept you'll use in production: REST APIs, database CRUD operations, JWT authentication, and deploying a frontend and backend separately. Build it once, understand the full stack.
Read More Success StoriesFrom Finance to Full-Stack Developer: An Illustrative 10-Month Journey
This composite illustrative story follows how a chartered accountant used financial modelling skills and systematic self-study to transition into full-stack development, landing a junior developer role in 10 months without a coding bootcamp.
Read More ProgrammingThe JavaScript Event Loop Explained Simply
The JavaScript event loop is the mechanism that lets single-threaded JavaScript handle async work by running queued callbacks whenever the call stack is empty.
Read More