{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreigdf4m554wr4yrzaqpc23vo7yup4armu5k6fcgh5ozfjmijgkqjwu",
    "uri": "at://did:plc:pi6woz4d47bkuws673w2il2r/app.bsky.feed.post/3mjj7ecxxqy72"
  },
  "path": "/t/why-we-built-a-haskell-package-manager-in-rust/13933#post_4",
  "publishedAt": "2026-04-15T05:46:18.000Z",
  "site": "https://discourse.haskell.org",
  "textContent": "> If you want to start a Haskell project today, here is what you do. First you install ghcup, which manages GHC (the compiler), Cabal (the build tool), Stack (a different build tool), and HLS (the language server). Then you decide whether to use Cabal or Stack, which is a decision that has split the Haskell community for over a decade and which nobody has fully resolved. Then you configure your project, using either a `.cabal` file (a custom format that predates TOML, YAML, and JSON as configuration languages) or a `stack.yaml` plus a `.cabal` file (because Stack still needs Cabal files underneath). Then you wait for GHC to compile your dependencies, which takes long enough that you start questioning your life choices.\n>\n> I am not exaggerating for effect. This is the actual experience. I have introduced Haskell to teams and watched the enthusiasm drain from people’s faces during the toolchain setup. Not because the language was hard. Because the first thirty minutes were spent fighting `ghcup`, `cabal update`, resolver mismatches, and cryptic build errors that had nothing to do with the code they wanted to write.\n>\n> Here is what a typical first encounter looks like. You want to write a small HTTP server in Haskell. You install ghcup. You install GHC 9.8.2. You run `cabal init`. You get a `.cabal` file with a dozen fields, most of which you do not understand yet. You add `warp` as a dependency. You run `cabal build`. GHC starts compiling `warp` and its transitive dependencies: `http-types`, `bytestring`, `text`, `network`, `streaming-commons`, `vault`, `wai`, and about forty others. This takes four to six minutes on a modern machine. The first time. Every time you switch GHC versions or clean your cache, you pay that cost again.\n>\n> Now compare this with Rust. You run `cargo new my-server`. You add `axum` to `Cargo.toml`. You run `cargo build`. It compiles. The first build is not instant either, but `cargo` does not ask you which of two incompatible build tools you prefer, does not require a separate tool to manage the compiler, and does not present you with a configuration format from 2005.\n\nI’m not sure this is a fair comparison. Why does ghcup get dinged for HLS but rust-analyzer gets skipped in the rust setup? Rust doesn’t have transitive dependencies?\n\nI think I spent just a few minutes getting tooling set up using ghcup the first time I tried. What exactly is enervating their enthusiasm during the tooling setup? I’m missing the advantage over cabal or guix/nix",
  "title": "Why We Built a Haskell Package Manager in Rust"
}