# haskell/cabal: one repository holding five packages and a three year support promise

> The upstream repository for the Cabal library, cabal-install and their supporting packages, with an unusually explicit statement of which GHC versions count as supported. Useful for reading how the Haskell packaging system is actually maintained.

**haskell/cabal** — Official upstream development repository for Cabal and cabal-install

- Repository: https://github.com/haskell/cabal
- Website: https://haskell.org/cabal
- Stars: 1,747 · Forks: 761
- Language: Haskell
- License: NOASSERTION
- Published: 2026-10-16 · Updated: 2026-10-16 · Language: en
- Canonical page: https://hysenlabs.com/projects/haskell-cabal

## Five packages in one tree, each with its own licence file

The repository description is precise: this is the official upstream development repository for Cabal and cabal-install. The README then lists the main packages it contains, and the list is the first thing to understand.

Cabal is the library package. Cabal-syntax is the library for the .cabal file format, which is a separate package because the file format has to be parsable by tools that are not the build tool. Cabal-hooks provides the API for the Hooks build type. cabal-install is the package containing the cabal tool itself, and cabal-install-solver holds the solver component separately from the tool.

That last split is the one to note. The solver is the part that decides which versions of which packages can satisfy a dependency set, and it is packaged independently, which is why the repository can have a solver benchmark directory, solver-benchmarks/, as a distinct concern from the main build.

Each package carries its own LICENSE file, and the project also has a LICENSE at the root. GitHub could not classify the licence, so if you are redistributing, read the file for the package you are taking.

The canonical upstream repository is stated to be the GitHub location, with a GitLab pipeline badge for release CI, so the GitHub repository is the source and GitLab runs the automation.

## Installing the tool is four routes with different trade-offs

Getting the cabal-install binary is documented as four ways, and which one you pick determines how painful your next upgrade is.

The preferred route is GHCup:

```bash
ghcup install --set cabal latest
```

The second is a binary download from the official website at haskell.org/cabal/download.html, where the download for your platform contains the cabal executable.

Preview releases are the third. These give you a chance to try unreleased features, and currently only x86_64 binaries are provided. A GitHub preview release built from the tip of master can be installed through GHCup:

```bash
ghcup install cabal -u https://github.com/haskell/cabal/releases/download/cabal-head/cabal-head-Linux-x86_64.tar.gz head
```

with Linux replaced by Windows or macOS as appropriate. The README warns that the default Linux build is dynamically linked against zlib, gmp and glibc, so those libraries need to be present, and that a statically linked Linux-static binary is also provided as an alternative.

Even further ahead are binaries built from pull requests, available from the Validate workflow page on GitHub or from the build-alpine workflow for static Linux builds.

Building it yourself is the fourth route, and there are three ways within it. With an existing cabal-install, cabal install cabal-install. From a clone, with an existing cabal-install again, using a specific project file:

```bash
cabal install --project-file=cabal.release.project cabal-install
```

And if you have no cabal-install at all, the bootstrap/ directory is where you start, which is the historical path and the slowest one.

## Running from master will break your build, and the README shows the fix

There is one configuration detail in this README that will save a day for anyone who tries a preview build.

If you install a cabal-head binary and then build a project, your build can fail because the Cabal library on your system is out of date relative to the tool. The fix is a stanza in your cabal.project file:

```
allow-newer:
  *:Cabal,
  *:Cabal-syntax

source-repository-package
    type: git
    location: https://github.com/haskell/cabal.git
    subdir: Cabal Cabal-syntax
```

allow-newer relaxes the upper bounds so a newer Cabal library is acceptable, and source-repository-package points the build at the git repository rather than the installed library.

This is worth understanding rather than copying. It is the practical shape of the library and tool split: the Cabal library is compiled into your package build, and the cabal tool is the thing driving it, so a newer tool can legitimately demand a newer library than your environment has.

It is also the reason the support window below exists. The project has to keep a new cabal-install working with older Cabal libraries, and allow-newer is the escape hatch when it cannot.

For a production dependency, use the released tool rather than the head build. The head releases exist so that changes can be tried before they ship, not so that they can be deployed.

## The three year support window is defined precisely, not vaguely

The README states a GHC support window of three years for both the Cabal library and cabal-install, and then defines what that means in four separate clauses.

The Cabal library must be buildable out of the box against the boot libraries shipped with GHC, for any GHC released in the past three years from the Cabal library release date.

cabal-install should be buildable with the bootstrap/bootstrap.py script for any GHC released in the past three years from its release date.

cabal-install should be able to drive the most recent minor version of any GHC's major version released in that same window, where drive means cabal-install will work with the Cabal library used to build the package, usually but not always the one that came with that GHC.

And self-upgrade to the latest version, meaning cabal install cabal-install, must work with all versions of cabal-install released during the last three years.

That last clause is the one that affects you daily. It is a promise that you can run cabal install cabal-install to move forward, which is the mechanism by which every Haskell developer upgrades their toolchain without manual intervention.

Beyond the window, maintainers try to support older GHC versions on a minimal effort basis. The word chosen is minimal, which is as precise as a promise like that can be.

## Governance runs through proposals and rough consensus, not votes

Changes to the Cabal ecosystem go through a proposals process documented in proposals.md, and its three properties are worth reading because they explain why this project moves at the speed it does.

It is light weight: a pull request is opened and discussed in a separate cabal-proposals repository with a fixed discussion period. It is developer led: final decisions are made by developers at the Cabal developers meeting. And it is flexible: there is no formal voting procedure, and decisions are made by rough consensus, which the README links to the RFC that defines that term.

Rough consensus is a specific mechanism rather than a vague aspiration. It works well when the people affected are present and the disagreement is technical. It works badly when a decision imposes costs on people who are not in the room, which for a packaging format used by every Haskell project is a real category.

The rest of the project structure supports the same picture. MAINTAINERS.md names who maintains what, CONTRIBUTING.md covers building for hacking, and release-checklist.md plus a release-notes/ directory and a changelog.d/ directory show that releases are a documented procedure rather than a tag. There is a cabal.validate.project and a cabal.validate-libonly.project, so the project validates itself as a package, and the Makefile check target runs cabal check across Cabal, cabal-install, Cabal-syntax, Cabal-hooks, hooks-exe and cabal-install-solver, requiring the output No errors or warnings could be found in the package from each.

## The repository is also a map of the Haskell toolchain's rough edges

The top level file list is the most informative documentation of what is hard about Haskell packaging, because every awkward directory corresponds to a real problem.

Cabal-tests/ and cabal-testsuite/ are the test suites. Cabal-QuickCheck/, Cabal-described/ and Cabal-tree-diff/ are supporting libraries. buildinfo-reference-generator/ exists to generate reference build information, which is a task that only needs doing because package metadata has to be precomputed somewhere. license-list-data/ holds dedicated licence data for the repository.

license-list-data/ deserves a second look. Licence fields identify applicable licence terms and may need updating when a new licence version is published. Having a dedicated directory for them says the format treats licensing as a first class concern, which is unusual and sensible.

The tooling files follow the same pattern of recorded pain..hlint.yaml for hint configuration, fourmolu.yaml plus fix-whitespace.yaml for formatting,.typos-docs.toml and.typos-srcs.toml as separate typo configurations for documentation and source,.git-blame-ignore-reqs as.git-blame-ignore-revs for large mechanical commits, and.githooks/ wired up by the Makefile init target which sets git config core.hooksPath to.githooks.

The continuous integration is split across GitHub workflows and a.gitlab-ci.yml, and the project files at the root are separate by purpose: cabal.project for development, cabal.release.project for releases, cabal.bootstrap.project for bootstrapping, and cabal.meta.project for the meta build. A stack.yaml is present too, which is an acknowledgement that not everyone builds with cabal.

The last push was on 2026-10-16 and the repository is not archived, with releases including cabal-head from 2026-10-14 and cabal-install v3.18.2.0 from 2026-09-30.

## Conclusion

Adopt cabal-install as your Haskell package manager and use this repository as the source when you need to know why the tool behaves as it does, since the split into Cabal, Cabal-syntax and cabal-install explains most surprising behaviour. Do not build from master expecting stability, because the head releases are cut from the branch tip and the README documents an allow-newer stanza you may need for exactly that reason. Before upgrading the tool, check the three year support window against your GHC version and read release-notes/ and changelog.d/, and prefer ghcup over a source build so the self-upgrade path stays inside the window the maintainers promise.

## FAQ

### How do I install the cabal tool?

The preferred route is ghcup install --set cabal latest. You can also download a binary from the official website, install a preview build from the cabal-head GitHub release, or build from source with an existing cabal-install via cabal install --project-file=cabal.release.project cabal-install.

### What packages live in the haskell/cabal repository?

Cabal, Cabal-syntax for the .cabal file format, Cabal-hooks for the Hooks build type API, cabal-install containing the cabal tool, and cabal-install-solver containing the solver component. Each package has its own LICENSE file.

### Which GHC versions does Cabal support?

A three year window, defined in the README for both the Cabal library and cabal-install, including that self-upgrade with cabal install cabal-install must work with all cabal-install versions released in that window. Older versions are supported on a minimal effort basis.

### Why does my build fail after installing a preview cabal build?

Because the installed Cabal library is out of date relative to the tool. The README shows the fix in cabal.project: an allow-newer stanza for *:Cabal and *:Cabal-syntax, plus a source-repository-package entry pointing at the git repository with subdir Cabal Cabal-syntax.

### How are changes to the Cabal project decided?

Through the proposals process in proposals.md: a pull request discussed in the cabal-proposals repository with a fixed period, final decisions made by developers at the Cabal developers meeting, and no formal voting, with decisions reached by rough consensus.

## Sources

- [haskell/cabal on GitHub](https://github.com/haskell/cabal)
- [Issues](https://github.com/haskell/cabal/issues)
- [Project website](https://haskell.org/cabal)
- [README](https://github.com/haskell/cabal/blob/master/README.md)
- [Releases](https://github.com/haskell/cabal/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/haskell-cabal
