# Garn: a Nix/Cabal/Stack alternative

**URL:** <https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265>\
**Category:** Announcements\
**Created:** [December 3, 2023, 4:10pm UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265 "2023-12-03T16:10:14Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![jkarni](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jkarni/32/3885_2.png) [@jkarni](https://discourse.haskell.org/u/jkarni)\
**Post date:** [December 3, 2023, 4:10pm UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/1 "2023-12-03T16:10:14Z")

</div>

# garn

garn is a new take on Nix - configured in Typescript rather than the Nix language, and with a nicer and simpler CLI (thanks optparse-applicative!). The repository is [here](https://github.com/garnix-io/garn), and the website is [here](https://garn.io/).

I’m mentioning it here because we just added better Haskell support, which makes it now a plausible alternative to managing your Haskell projects with Nix, Stack or Cabal. An example Haskell project:

```typescript
  import * as garn from "https://garn.io/ts/v0.0.18/mod.ts";
  import * as pkgs from "https://garn.io/ts/v0.0.18/nixpkgs.ts";

  export const project = garn.haskell.mkHaskellProject({
    description: "My project",
    src: ".",
    executables: ["server", "openapi-generation"]
    overrideDependencies: {
      "servant": "0.19.1"
    },
    ghcVersion: "ghc94"
  }).addExecutable("format")`${pkgs.ormolu}/bin/ormolu --mode inplace $(find . -name '*.hs')`

```

Which allows for `garn build project` to build the project, and `garn enter project` to be in a devshell with cabal, ghc94 and all the dependencies installed, and `garn run project.format` for formatting all files with ormolu.

(`garn init` is capable of generating most of that file for you.)

# Comparisons

First, compared to all of the options below, garn is much less mature - there’ll be rougher edges or features not yet supported. It’s also still changing very quickly, and backwards compatibility is not, for now, a priority.

- **Cabal** : Like Cabal, garn still uses a cabal file, and in fact expects you to  
develop with cabal. garn brings in the dependencies itself and makes them  
known to ghc/cabal, and they’re snapshot-based rather than resolver-based. In  
addition, garn makes it easy to include system (non-Haskell) dependencies, it  
sandboxes builds and tests for better reproduciblity (making CI in particular  
quite easy); it allows for shared caches; it supports scripts for project  
janitoring and management; and it supports devshells.

- **Stack** : Like Stack, garn uses a snapshot-based approach to dependencies. In  
fact, it’s based on the stackage releases. It also supports overriding  
versions from Hackage, but not yet from git. Unlike Stack, it allows  
specifying system dependencies (non-Haskell dependencies); it sandboxes  
builds and tests for better reproduciblity (making CI in particular quite  
easy); it allows for shared caches; it supports scripts for project  
janitoring and management; and it supports devshells.

- **Nix** : the focus of garn has been a simplified and more productive user  
experience when compared to Nix. A typed language means you can get  
autocompletion, documentation, and type errors in your editor, for example.  
And, even if Typescript is by no means perfect, it’s much easier to program  
in than Nix, so it becomes more fun to abstract away functionality (e.g.: an  
addGhcidToProject function). garn “transpiles” to Nix, and Nix can be  
embedded in garn, so the choice is not binary.

# Feedback appreciated!

If you try it out, please let us know what you think, or if you run into any roadblocks. You can message me or open issues [on GitHub](https://github.com/garnix-io/garn), or join the [Discord channel](https://discord.com/invite/XtDrPsqpVx) at.

It also happens to be partly written in Haskell; hopefully that makes it more easy and fun to get involved!

Cheers,  
Julian

---

<div class="post-metadata">

**Author:** ![cdepillabout](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/cdepillabout/32/1168_2.png) [@cdepillabout](https://discourse.haskell.org/u/cdepillabout)\
**Post date:** [December 5, 2023, 6:17am UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/2 "2023-12-05T06:17:55Z")

</div>

Great to see more innovation in this space!

I had one question about the Haskell support: Is this based on Nixpkgs Haskell infrastructure, or haskell.nix?

To answer this for myself, it appears to be based on the Nixpkgs Haskell infrastructure:

> <https://github.com/garnix-io/garn/blob/ab0f01fc82c976d4f6c1136d9fb1079b613a77a4/ts/haskell/mod.ts#L54>

---

<div class="post-metadata">

**Author:** ![juhp](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/juhp/32/323_2.png) [@juhp](https://discourse.haskell.org/u/juhp)\
**Post date:** [December 8, 2023, 2:02am UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/3 "2023-12-08T02:02:09Z")

</div>

I am curious if it can handle being used from a shared home dir across different Linux OS versions, say? (eg think distrobox or toolbox containers)

I think neither cabal nor stack handle this particularly well.

---

<div class="post-metadata">

**Author:** ![jkarni](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jkarni/32/3885_2.png) [@jkarni](https://discourse.haskell.org/u/jkarni)\
**Post date:** [December 8, 2023, 8:56am UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/4 "2023-12-08T08:56:11Z")

</div>

> [@juhp](#):
>
> distrobox

I haven’t tried it, but my guess is that if it’s Linux and Linux, then yes!

---

<div class="post-metadata">

**Author:** ![janus](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/janus/32/1060_2.png) [@janus](https://discourse.haskell.org/u/janus)\
**Post date:** [December 8, 2023, 3:59pm UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/5 "2023-12-08T15:59:55Z")

</div>

If Garn compiles to Nix, how do you decide which Nixpkgs to be compatible with? I imagine that there has to be some kind of restriction on which versions of Nixpkgs you can use, since Nixpkgs changes its API.

---

<div class="post-metadata">

**Author:** ![jkarni](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.haskell.org/jkarni/32/3885_2.png) [@jkarni](https://discourse.haskell.org/u/jkarni)\
**Post date:** [December 9, 2023, 12:43pm UTC](https://discourse.haskell.org/t/garn-a-nix-cabal-stack-alternative/8265/6 "2023-12-09T12:43:47Z")

</div>

> If Garn compiles to Nix, how do you decide which Nixpkgs to be compatible with? I imagine that there has to be some kind of restriction on which versions of Nixpkgs you can use, since Nixpkgs changes its API.

Yeah, there’s a supported nixpkgs commit for each garn release (though for binaries alone you could mix and match).
