How can I (or maybe why can't I...) install system-wide via ghcup?

I can see in the install script that for unix-like systems we install everything into the user’s $HOME directory. What if I want to install everything system-wide (for instance at /opt/ghcup or even /opt/haskell)?

I know that I can set the GHCUP_INSTALL_BASE_PREFIX but it’s still trying to append $GHCUP_INSTALL_BASE_PREFIX/.ghcup and if I want to install to /opt I need to borrow root permissions, so I end up with a mess at /root/.ghcup.

I can move the .ghci directory from my home directory, but then every time I try to update or install something it gets put in $HOME/.ghcup (or tries to do something like mkdir /opt/ghcup/.ghcup).

Am I missing something?

In case not: was it a deliberate choice to bake in the $HOME? And is it a feature request that I could reasonably send? I found one issue discussing this (ghcup-hs/#39), but it was dropped.

Generally speaking, the world is moving towards user-local installing (when it’s not your system distribution/OS doing the installing). I’m not sure whether that’s good or bad, but it is what it is.

In the case of ghcup it’s probably because it may sometimes require very specific combos of GHC+Cabal/Stack+HLS to work properly. It’s complicated, I’m afraid.

Are you doing CI stuff, or…?


The linked ticket explains why “.ghcup” is part of where things end up even if you’ve passed in another base directory: “The current design gives us this safety guarantee that .ghcup is managed by ghcup and nothing about the parent directories is known.”


You can do system wide installation via --isolate=dir.


GHCup will, however, know nothing about the installation and will not offer to uninstall it.

This can be conveniently used in CI or managed settings.

Installing into arbitrary locations is not an easy design space and in fact already had a grave bug that was luckily hard to trigger. This caused me to rewrite large parts of the installation handling, by e.g. separating user input dirs from “safe” internal dirs on type level.


Thanks! This seems to work well for my use case.

More “or” … wanted to install to a common place on a system with many users collaborating.