# How much effort does backwards compatibility require from library authors?

**URL:** https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584
**Category:** Learn
**Created:** [March 9, 2025, 8:46pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584 "2025-03-09T20:46:57Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![malteneuss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/malteneuss/32/2541_2.png) [@malteneuss](https://discourse.haskell.org/u/malteneuss)
#### Post date: [March 9, 2025, 8:46pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/1 "2025-03-09T20:46:57Z")

</div>

From people i follow on Github i noticed a few **pull requests** that introduce support for the GHC version `9.12` but **drop support for** older (but not that old) **GHC versions like `9.6`** , e.g. [Add support for GHC 9.12, drop support for GHC 9.6 by tfausak · Pull Request #118 · tfausak/witch · GitHub](https://github.com/tfausak/witch/pull/118/files) and [Drop support for GHC \< 9.8 by brandonchinn178 · Pull Request #36 · brandonchinn178/toml-reader · GitHub](https://github.com/brandonchinn178/toml-reader/pull/36/files).

Without any blame **i’m curious why that is** , because `9.6` seems to be an actively maintained version yet (see [GHC versions: downloading and status · Wiki · Glasgow Haskell Compiler / GHC · GitLab](https://gitlab.haskell.org/ghc/ghc/-/wikis/GHC-status)) and for official Nixpkgs users like me `9.6` is still the latest version (until [haskellPackages: Stackage LTS 22 -\> 23; ghc: 9.6.6 -\> 9.8.4 by sternenseemann · Pull Request #371032 · NixOS/nixpkgs · GitHub](https://github.com/NixOS/nixpkgs/pull/371032) gets merged).

**Is maybe the maintenance churn** of keeping backwards-compatibility with GHC (doesn’t seem so in these specific PRs) or third-party tools like Github actions **high**? I’m asking, because in order to make Haskell more appealing to commercial companies **migration paths should be as simple as possible and low-risk** , i.e. if GHC can’t be backwards-compatible sometimes, then maybe the libraries can be, so that users d **on’t have to upgrade both at the same time**. I think @angerman emphasized that a few times already, but i can’t find the post right now.

---

<div class="post-metadata">

### Author: ![Ambrose](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ambrose/32/5672_2.png) [@Ambrose](https://discourse.haskell.org/u/Ambrose)
#### Post date: [March 9, 2025, 9:21pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/2 "2025-03-09T21:21:32Z")

</div>

I agree dropping support for 9.6 is a bit aggressive for 2025. That is odd to me for such general libraries.

---

<div class="post-metadata">

### Author: ![jackdk](https://avatars.discourse-cdn.com/v4/letter/j/9f8e36/32.png) [@jackdk](https://discourse.haskell.org/u/jackdk)
#### Post date: [March 9, 2025, 9:50pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/3 "2025-03-09T21:50:17Z")

</div>

Two of your linked PRs involve changes to `template-haskell` bounds, and making libraries compatible with multiple versions of `template-haskell` can be tricky sometimes. I can understand the desire to limit the range of GHC versions to keep things simple.

But this is the first time I’ve seen someone call out aggressive dropping of support for old GHCs, and it’s a little surprising to me - the rule of thumb we use for work FOSS packages is:

- At least the three most recent stable GHC releases, plus
- Whatever GHC series we’re using internally (currently, we’re on GHC 9.6), plus
- Any older GHC versions that happen to still work (but we’ll raise the `base` lower bound, not reach for CPP, if they stop working; that said, it’s often been fine and some of our simpler packages still support GHC 8.10.7)

It probably bears repeating: **work is still on GHC 9.6**. This is primarily because `amazonka` hasn’t had a release that supports GHC \>= 9.8 (it’s on `main`, and I’m sorry it hasn’t progressed beyond that).

I think part of the reason it feels weird here is that both GHC 9.6.1 and 9.8.1 came out in 2023 (if the Discourse posts’ dates are correct), and because GHC 9.12.1 is still “not recommended for use” in the [GHC downloading and status](https://gitlab.haskell.org/ghc/ghc/-/wikis/GHC-status) page linked by the OP. Given that GHC 9.12.1 has an issue that causes [incorrect runtime behaviour](https://gitlab.haskell.org/ghc/ghc/-/issues/25653), it’s probably correct that it’s been marked “not recommended for use”.

IMHO, a healthy starting point for most libraries (that aren’t locked to GHC internals for some reason) would be to support the “suitable for use” major releases, plus any newer GHC series as they mature. Maintaining support for older GHCs is a nice favour, but I don’t expect the average library maintainer to do that forever. (MicroHS is another potential reason to use simpler Haskell in libraries than one would in applications.)

For library consumers, I generally think that “if upgrading is too hard, it’s probably not happening frequently enough”. Work’s codebase is relatively small compared to others I’ve heard about (~120kLoC Haskell) and keeping it up-to-date is not too bad. I’ve also heard about larger codebases where a GHC upgrade is a year-long project. It seems better to me that upgrading is done frequently and with little friction than to have to worry about big-bang GHC-and-library upgrades (though we don’t want to go as fast as the JS ecosystem, of course). Otherwise, nobody gets to _actually use_ the new things that people have been tirelessly working on. The biggest example of this is something like Backpack, which AFAICT nobody uses because Stack doesn’t support it, and Stack doesn’t support it because nobody uses it.

---

<div class="post-metadata">

### Author: ![Bodigrim](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/bodigrim/32/1457_2.png) [@Bodigrim](https://discourse.haskell.org/u/Bodigrim)
#### Post date: [March 10, 2025, 12:13am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/4 "2025-03-10T00:13:40Z")

</div>

Why would a maintainer commit to do additional work for older GHCs? Previous releases are not going anywhere, you can keep using them with GHC 9.6.

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 10, 2025, 12:43am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/5 "2025-03-10T00:43:17Z")

</div>

I have limited bandwidth to maintain my packages. Supporting more versions of GHC (or any dependency!) is often easy, but it’s never free. My policy is to support the latest three major versions of GHC.

---

<div class="post-metadata">

### Author: ![jackdk](https://avatars.discourse-cdn.com/v4/letter/j/9f8e36/32.png) [@jackdk](https://discourse.haskell.org/u/jackdk)
#### Post date: [March 10, 2025, 3:09am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/6 "2025-03-10T03:09:37Z")

</div>

This seems reasonable and common, but I wonder if supporting the three most recent “suitable for use” major releases (per the wiki page in OP) would be a better standard?

---

<div class="post-metadata">

### Author: ![sgraf](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/sgraf/32/392_2.png) [@sgraf](https://discourse.haskell.org/u/sgraf)
#### Post date: [March 10, 2025, 7:56am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/7 "2025-03-10T07:56:51Z")

</div>

It sounds to me like the ideal solution would be commercial users funding maintenance for the configuration they are using. Sounds like that wouldn’t be too much of a time sink, while it’s a lot to ask of maintainers to gift companies this kind of busywork in their free time.

---

<div class="post-metadata">

### Author: ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)
#### Post date: [March 10, 2025, 8:18am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/8 "2025-03-10T08:18:19Z")

</div>

> [@taylorfausak](#):
>
> I have limited bandwidth to maintain my packages. Supporting more versions of GHC (or any dependency!) is often easy, but it’s never free. My policy is to support the latest three major versions of GHC.

> [@Bodigrim](#):
>
> Why would a maintainer commit to do additional work for older GHCs? Previous releases are not going anywhere, you can keep using them with GHC 9.6.

I’m curious whether there are specific issues making packages work with 9.12 which prevented keeping the lower bound where it was. If so then I will add them to my [9.12 breakage inventory](https://github.com/tomjaguarpaw/tilapia/blob/master/breakage-inventory-ghc-9.12.md#ghc-912-breakage-inventory).

---

<div class="post-metadata">

### Author: ![TeofilC](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/teofilc/32/3987_2.png) [@TeofilC](https://discourse.haskell.org/u/TeofilC)
#### Post date: [March 10, 2025, 1:38pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/9 "2025-03-10T13:38:37Z")

</div>

> [@jackdk](#):
>
> Two of your linked PRs involve changes to `template-haskell` bounds, and making libraries compatible with multiple versions of `template-haskell` can be tricky sometimes.

This is a good point. I think the GHC-9.12 release of TH should’ve been easy to upgrade to, but I’d be interested in hearing if not.

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 10, 2025, 1:53pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/10 "2025-03-10T13:53:05Z")

</div>

I didn’t know that page existed before yesterday. The “suitable for use” distinction is new to me. However it’s not the first time an X.Y.1 release has had bugs. I’d prefer to support the latest release even if it’s not suitable so that people who aren’t affected by the bug can upgrade.

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 10, 2025, 1:57pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/11 "2025-03-10T13:57:17Z")

</div>

You can see all my PRs for upgrading to GHC 9.12 here:

> <https://github.com/tfausak/haskell-packages/pull/19>
>
> \- \[x\] \[autoexporter\](https://github.com/tfausak/autoexporter): https://github.co…m/tfausak/autoexporter/pull/38
> \- \[x\] \[burrito\](https://github.com/tfausak/burrito): https://github.com/tfausak/burrito/pull/43
> \- \[x\] \[cabal-gild\](https://github.com/tfausak/cabal-gild): https://github.com/tfausak/cabal-gild/pull/112
> \- \[x\] \[flow\](https://github.com/tfausak/flow): https://github.com/tfausak/flow/pull/44
> \- \[x\] \[github-release\](https://github.com/tfausak/github-release): https://github.com/tfausak/github-release/pull/41
> \- \[x\] \[imp\](https://github.com/tfausak/imp): https://github.com/tfausak/imp/pull/39
> \- \[x\] \[json-feed\](https://github.com/tfausak/json-feed): https://github.com/tfausak/json-feed/pull/29
> \- \[x\] \[lackey\](https://github.com/tfausak/lackey): https://github.com/tfausak/lackey/pull/33
> \- \[x\] \[patrol\](https://github.com/tfausak/patrol): https://github.com/tfausak/patrol/pull/26
> \- \[x\] \[rampart\](https://github.com/tfausak/rampart): https://github.com/tfausak/rampart/pull/30
> \- \[x\] \[ratel\](https://github.com/tfausak/ratel): https://github.com/tfausak/ratel/pull/31
> \- \[x\] \[ratel-wai\](https://github.com/tfausak/ratel-wai): https://github.com/tfausak/ratel-wai/pull/25
> \- \[x\] \[rattletrap\](https://github.com/tfausak/rattletrap): https://github.com/tfausak/rattletrap/pull/323
> \- \[x\] \[salve\](https://github.com/tfausak/salve): https://github.com/tfausak/salve/pull/34
> \- \[x\] \[saturn\](https://github.com/tfausak/saturn): https://github.com/tfausak/saturn/pull/21
> \- \[x\] \[strive\](https://github.com/tfausak/strive): https://github.com/tfausak/strive/pull/143
> \- \[x\] \[witch\](https://github.com/tfausak/witch): https://github.com/tfausak/witch/pull/118
> \- \[x\] \[wuss\](https://github.com/tfausak/wuss): https://github.com/tfausak/wuss/pull/53

None of them required any code changes.

---

<div class="post-metadata">

### Author: ![Ambrose](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ambrose/32/5672_2.png) [@Ambrose](https://discourse.haskell.org/u/Ambrose)
#### Post date: [March 10, 2025, 6:59pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/12 "2025-03-10T18:59:23Z")

</div>

If they don’t require code changes, why drop support for 9.6? Doesn’t that mean that they _do_ build with 9.6?

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 11, 2025, 1:10am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/13 "2025-03-11T01:10:01Z")

</div>

Why stop there? My Flow library hasn’t really had any code changes since it was released in 2015 ([then](https://github.com/tfausak/flow/blob/7176051e6e29cb7efada7983b1b34b4ca234343b/Flow.hs#L1), [now](https://github.com/tfausak/flow/blob/d0186b726f60015702b79f32e9f35c07c815effb/source/library/Flow.hs#L35)). Should I still be supporting GHC 8.0? I’ll bet Flow compiles with even older versions of GHC as well — perhaps I should add support for everything back to GHC 6.6, around when Hackage showed up.

Less glibly, any support policy I make is going to exclude some people with totally valid use cases. To those people, I’ll echo what Andrew said earlier in the thread: Use an older version of my libraries to go with the older versions of GHC. Or, if that’s not palatable, use something like Cabal’s `--allow-older` flag. Or if even that doesn’t work, I’ll echo what Sebastian said: Pay me and I’ll (probably) support whatever you need.

---

<div class="post-metadata">

### Author: ![Ambrose](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ambrose/32/5672_2.png) [@Ambrose](https://discourse.haskell.org/u/Ambrose)
#### Post date: [March 11, 2025, 2:04am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/14 "2025-03-11T02:04:47Z")

</div>

What cost is there to not bumping the PVP lower bound when it’s observably unnecessary (like this case)?

I get not wanting to maintain a gigantic matrix of GHC versions in your library’s CI. That’s nontrivial. But that’s what `tested-with` is for. I also get needing to maintain a bunch of `CPP` or w/e to maintain compat. But you can just not do all that while not bumping the lower bound. It’s not a signal of future maintenance. Just that the current version works.

Worst case, you’re wrong and a user on an old GHC lets you know and you bump the lower bound _then_. Decentralized CI 😆

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 11, 2025, 2:22am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/15 "2025-03-11T02:22:38Z")

</div>

Why is it up to me to support the versions of GHC that you want? This is how I’ve chosen to maintain my packages. I have my reasons, but it sounds like they don’t resonate with you. That’s fine.

---

<div class="post-metadata">

### Author: ![ikervagyok](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/ikervagyok/32/4199_2.png) [@ikervagyok](https://discourse.haskell.org/u/ikervagyok)
#### Post date: [March 11, 2025, 7:48am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/16 "2025-03-11T07:48:36Z")

</div>

I’d like to comment from a different user perspective:

Thank you library maintainers, for giving me the option to use a recent GHC in a timely manner! The situation is so much better than a few years ago.

I don’t ~~care about~~ _have an issue with_ using slightly older packages or trying to allow newer versions with an older version of GHC, as long as there is a working combination.

_Edit: clarify_

---

<div class="post-metadata">

### Author: ![tomjaguarpaw](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/tomjaguarpaw/32/1230_2.png) [@tomjaguarpaw](https://discourse.haskell.org/u/tomjaguarpaw)
#### Post date: [March 11, 2025, 8:07am UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/17 "2025-03-11T08:07:16Z")

</div>

> [@taylorfausak](#):
>
> This is how I’ve chosen to maintain my packages. I have my reasons, but it sounds like they don’t resonate with you. That’s fine.

Naturally, you’re welcome to maintain your packages however you want for any reason or no reason at all. Sorry if you’ve already shared and I’ve either missed it or misunderstood, but I don’t think I know what your reasons are. Would you mind elaborating?

In the case of `witch`, for example, [it looks like](https://github.com/tfausak/witch/pull/118/files) it would actually have been easier to keep support for 9.4 than drop it, as that would have required fewer changes to cabal and CI files. But maybe the reason is something else? For example, the simplicity that comes from knowing _all_ the packages you maintain support _exactly_ the same version range. I don’t want to put words into your mouth though: I’m just guessing here.

---

<div class="post-metadata">

### Author: ![taylorfausak](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/taylorfausak/32/54_2.png) [@taylorfausak](https://discourse.haskell.org/u/taylorfausak)
#### Post date: [March 11, 2025, 2:01pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/18 "2025-03-11T14:01:35Z")

</div>

For me it’s not about any particular version of GHC. Sometimes it would not require much to maintain support, other times it would require a lot. I would prefer to have a policy that is easy to reason about (“latest three major versions”) rather than one that might have more supported configurations somewhat randomly (“whatever is easy to support”).

For Witch and GHC 9.6 specifically, I was about to drop something relatively minor from the package description:

```haskell
  if impl(ghc >=9.8)
     ghc-options: -Wno-missing-role-annotations

```

I will take some time to write up a longer post with my actual rationale for my maintenaince policy. In the meantime, I will continue to push back against the implied assertion that I should continue to support GHC because it’s easy. Is anyone actually impacted by this? All of my packages have many released versions that work with GHC 9.6.

---

<div class="post-metadata">

### Author: ![chrisdone](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/chrisdone/32/1408_2.png) [@chrisdone](https://discourse.haskell.org/u/chrisdone)
#### Post date: [March 11, 2025, 7:38pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/19 "2025-03-11T19:38:29Z")

</div>

I keep a stable API for my packages, but I don’t give any thought to backwards compatibility wrt. GHC. Forwards compatibility tends to come for free by users of the package who are excited about the newest GHC out in the form of a PR. Amount of work for me is close to zero.

My assumption is that, like myself, people use Stackage or Nix’s haskellPackages (derived from Stackage), and use the version of a given package that’s appropriate for their version of GHC.

---

<div class="post-metadata">

### Author: ![malteneuss](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/malteneuss/32/2541_2.png) [@malteneuss](https://discourse.haskell.org/u/malteneuss)
#### Post date: [March 11, 2025, 8:28pm UTC](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584/20 "2025-03-11T20:28:56Z")

</div>

Thanks for the responses.

So far the discussion mostly evolved around “latest three major versions” policy. I’m very interested to read the rationale for it at some point, because my speculation would be that it’s a valid and pragmatic choice to reduce maintenance overhead (code, ci, discussions etc.) but could be alleviated with a larger Haskell user base to distribute the work. The same goes for a no-explicit-backwards-compatibility.

[Next page](https://discourse.haskell.org/t/how-much-effort-does-backwards-compatibility-require-from-library-authors/11584.md?page=2)
