Haskell ghcup

ID

ghcup

Links

Home page · Documentation · Repository

Upstream stars

⭐ 354

Last commit

2026-09-04

Version requirement

>= 0.2.1

Platforms

🐧 Linux · 🍎 macOS · 🪟 Windows

Operations

installed · search · install · remove · sync · cleanup

purl types

pkg:ghcup/

CLI name

ghcup

Forced environment

GHCUP_SKIP_UPDATE_CHECK=1
NO_COLOR=1

Issues and PRs

📦 manager: ghcup

Source

ghcup.py

Haskell toolchain installer, covering GHC and the tools built around it.

ghcup installs several kinds of tool side by side: GHC itself, plus cabal, hls, stack and whatever else its metadata offers. All of them are packages here, because ghcup list reports every kind in one flat listing whose every line names its own kind, and because install, rm, set and whereis all take the same <tool> <version> pair. Reporting only GHC versions would hide from the inventory tools mpm remains perfectly able to install and remove.

A package is therefore identified as <tool>-<version>, and split back on its first hyphen to rebuild the pair. First rather than last is required: a cross-compiling GHC renders its target into the version cell, so ghc-aarch64-unknown-linux-gnu-9.4.8 has to split into ghc and aarch64-unknown-linux-gnu-9.4.8, and that remainder is exactly the token ghcup’s own version parser accepts. No tool name contains a hyphen today.

What mpm adds to ghcup

Through mpm, ghcup gains --exact and --extended search, to narrow to exact names or match descriptions.

Bigger still, mpm reaches across every manager at once: mpm installed and mpm outdated cover ghcup alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.

Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.

Your ghcup commands, in mpm

You already know ghcup: each operation maps one-to-one onto mpm, in an interface shared by every manager.

To…

With ghcup

With mpm

List what’s installed

ghcup list --raw-format --show-revisions none --show-criteria installed

mpm --ghcup installed

Search for a package

ghcup list --raw-format --show-revisions none

mpm --ghcup search none

Install a package

ghcup install ghc 9.6.7

mpm install pkg:ghcup/ghc

Remove a package

ghcup rm ghc 9.6.7

mpm remove pkg:ghcup/ghc

Clear caches

ghcup gc --cache --tmpdirs

mpm --ghcup cleanup --cache

Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.

Operations

Operation

Supported

Notes

installed

✅

outdated

❌

The version is part of the package id, so a newer version is a different package installed alongside, not an upgrade of this one.

orphans

search

✅

Exact and extended search backfilled by mpm.

install

✅

upgrade

❌

The ghcup upgrade command upgrades the ghcup binary itself, and a tool has no in-place upgrade at all.

upgrade_all

❌

The ghcup upgrade command upgrades the ghcup binary itself, not the packages it manages.

remove

✅

sync

✅

cleanup

✅

doctor

Configuration

  • Ignore ghcup on the mpm CLI by passing the --no-ghcup option.

  • Ignore it for every run in your configuration:

    [mpm]
    ghcup = false
    
  • Raise the timeout of all ghcup calls:

    [mpm.overrides.ghcup]
    timeout = 900
    
  • Run mpm config-template ghcup to print all overridable settings for your configuration file:

    [mpm.overrides.ghcup]
    cli_names = [
        "ghcup",
    ]
    cli_search_path = []
    dry_run = false
    ignore_auto_updates = true
    plan = false
    post_args = []
    pre_args = []
    pre_cmds = []
    requirement = ">=0.2.1.0"
    stop_on_error = false
    unmaintained = false
    version_cli_options = [
        "--numeric-version",
    ]
    version_regexes = [
        "^(?P<version>\\d+(?:\\.\\d+)+)",
    ]
    
    [mpm.overrides.ghcup.extra_env]
    NO_COLOR = "1"
    GHCUP_SKIP_UPDATE_CHECK = "1"
    

The arguments and environment variables listed in the box atop this page are forced on every ghcup call, so runs stay quiet, non-interactive and reproducible: the defaults you would set in CI anyway.

Recipes

A few jobs you would otherwise script around ghcup, one mpm command each:

  • Snapshot and clone a machine: mpm --ghcup dump ghcup.toml, then mpm restore ghcup.toml on the next one.

  • Export a compliance SBOM: mpm --ghcup sbom (CycloneDX by default, --spdx for SPDX).

Privilege escalation

mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.

None of its operations is privileged.

See privilege escalation for the full policy.

Cooldown

State of Haskell ghcup’s release-age gating, from the cooldown support table:

Status: ❌ None

A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:

  • Registry: Haskell toolchain bindists

  • Retraction: None published: bindists are static artifacts named by ghcup’s own metadata file, which carries no yank or unlist surface; withdrawing a release means the Haskell.org release team editing the metadata that describes it

  • Publish date: ✅ the metadata records a release day per version, which ghcup list renders in its notes column

With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --cooldown best-effort opts back in.

Reference traces

A collection of raw native outputs captured from the manager’s own CLI and recorded in the manager source. If you know Haskell ghcup well and a transcript below looks wrong, or a newer release changed its output format, report it.

$ ghcup list --raw-format --show-revisions none --show-criteria installed
cabal 3.14.2.0 recommended
ghc 9.6.7 recommended,base-4.18.3.0
ghcup 0.2.6.2  stray

Version check

The version is probed by running:

$ ghcup --numeric-version
0.2.6.2

and extracted with:

r"^(?P<version>\d+(?:\.\d+)+)"

Upstream project

Metrics

haskell/ghcup-hs

Activity

commit activity commits since open issues open pull requests

Popularity

forks watchers contributors

Metadata

latest release release date license main language

Changelog

  • 8.0.0 (2026-09-20)

    • Add the Haskell ghcup toolchain installer with installed, search, install, remove, sync and cleanup support, every tool keyed as <tool>-<version>. It declares neither upgrade operation, ghcup upgrade replacing the ghcup binary itself.