{"id":13626364,"url":"https://github.com/garnix-io/garn","last_synced_at":"2025-10-29T02:20:04.942Z","repository":{"id":200883330,"uuid":"649775812","full_name":"garnix-io/garn","owner":"garnix-io","description":"garn is a build tool and environment manager that replaces justfiles/makefiles, docker, and the annoying parts of READMEs. The builders lingua franca. ","archived":false,"fork":false,"pushed_at":"2024-01-29T17:49:53.000Z","size":25961,"stargazers_count":251,"open_issues_count":70,"forks_count":6,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-11-08T16:43:12.295Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://garn.io","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/garnix-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-05T15:54:41.000Z","updated_at":"2024-11-07T23:06:53.000Z","dependencies_parsed_at":"2024-01-29T19:34:44.927Z","dependency_job_id":null,"html_url":"https://github.com/garnix-io/garn","commit_stats":null,"previous_names":["garnix-io/garn"],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garnix-io%2Fgarn","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garnix-io%2Fgarn/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garnix-io%2Fgarn/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/garnix-io%2Fgarn/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/garnix-io","download_url":"https://codeload.github.com/garnix-io/garn/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249250820,"owners_count":21237961,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T21:02:16.373Z","updated_at":"2025-10-29T02:19:59.884Z","avatar_url":"https://github.com/garnix-io.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","others","Build techniques"],"sub_categories":["Supply chain beyond libraries"],"readme":"\n\u003ch1 align=\"center\"\u003e\n\u003ca href=\"https://garn.io\"\u003e\n  \u003cimg src=\"./garn.png\"\u003e\n\u003c/a\u003e\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ci align=\"center\"\u003eThe Builders' Lingua Franca\u003c/i\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\n[![built with garnix](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fgarnix.io%2Fapi%2Fbadges%2Fgarnix-io%2Fgarn)](https://garnix.io)\n[![](https://dcbadge.vercel.app/api/server/q2Fptb7My4?style=flat)](https://discord.gg/q2Fptb7My4)\n[![](https://img.shields.io/badge/library-v0.0.20-black)](https://doc.deno.land/https://garn.io/ts/v0.0.20/mod.ts)\n[![License](https://img.shields.io/github/license/garnix-io/garn)](LICENSE)\n\n\u003c/p\u003e\n\n\n**garn** is a build tool and development environment manager. You configure your\nproject with a `garn.ts` file that declaratively describes your project and its\ndependencies.\n\nYou can think of it as coding up your README. Users, collaborators, and\ncoworkers no longer need to manually follow install steps, or figure out what\ncommands they can run, but instead can just use **garn** directly. And if it\nworks for you, it works for everyone.[^1]\n\n\nFor example, with this `garn.ts` file:\n\n```typescript\nimport * as garn from \"https://garn.io/ts/v0.0.20/mod.ts\";\n\nexport const frontend = garn.javascript.mkNpmProject({\n  description: \"My project frontend\",\n  src: \"frontend\",\n  nodeVersion: \"18\",\n})\n  .addExecutable(\"run\", \"cd frontend \u0026\u0026 npm install \u0026\u0026 npm start\");\n\nexport const backend = garn.go.mkGoProject({\n  description: \"My project backend\",\n  src: \"backend\",\n  goVersion: \"1.21\",\n})\n  .addExecutable(\"run\", \"cd backend \u0026\u0026 go run ./main.go\");\n\nexport const startAll = garn.processCompose({\n  frontend: frontend.run,\n  backend: backend.run,\n});\n```\n\nAnyone can run your frontend with `garn run frontend`, backend with `garn run\nbackend`, or both with `garn run startAll`. All without needing to worry about\nhaving the correct version of `go`, `nodejs`, or anything else installed.\n\nYou may have noticed the use of import URLs in the file above. This is supported\nby Deno, which we use under the hood. But you don't need to install that either.\nIn fact, **garn** might just be one of the last things you have to manually\ninstall.[^2]\n\n**garn** is powered by [Nix](https://nixos.org/), so you get portable and\nreproducible builds and development environments.\n\n\n---\n\n## Table of contents\n\n- [Getting Started](#getting-started)\n- [Commands](#commands)\n- [Core Concepts](#core-concepts)\n- [Languages and stacks](#languages-and-stacks)\n- [How it works](#how-it-works)\n- [Comparison to other tools](#comparison-to-other-tools)\n- [Typescript API](#typescript-api)\n\n## Getting started\n\n1) **Install garn**:\n\n   ```bash\n   sh \u003c(curl --proto '=https' --tlsv1.2 -sSf https://garn.io/install.sh)\n   ```\n\n   `garn` needs [`nix`](https://nixos.org/) to be installed, so if you don't\n   have nix already the above installer will install nix first, after asking\n   for confirmation.\n\n   \u003cdetails\u003e\n     \u003csummary\u003eManual install (Optional)\u003c/summary\u003e\n     If you prefer to know exactly what \u003cb\u003egarn\u003c/b\u003e is doing, or if you have a\n     special setup not covered by our installation script, you can see\n     \u003ca href=\"https://garn.io/docs/getting_started\"\u003ethis page\u003c/a\u003e for manual installation\n     steps.\n   \u003c/details\u003e\n\n   \u003cdetails\u003e\n     \u003csummary\u003eInstalling shell completion (Optional)\u003c/summary\u003e\n     You can also install shell completion scripts for the most popular shells.\n     See \u003ca href=\"https://garn.io/docs/getting_started\"\u003ethis page\u003c/a\u003e for more information.\n   \u003c/details\u003e\n\n   \u003cdetails\u003e\n     \u003csummary\u003eDeno LSP for garn files (Optional)\u003c/summary\u003e\n     \u003cb\u003egarn\u003c/b\u003e is much nicer with an IDE-like experience. You can use\n     \u003ccode\u003egarn edit\u003c/code\u003e for that or, if you prefer, you can set up your own editor.\n     See \u003ca href=\"https://garn.io/docs/getting_started\"\u003ethis page\u003c/a\u003e for more information\n   \u003c/details\u003e\n\n2) **Create your first `garn.ts` file**:\n\n   You can use `garn init` to template out an initial configuration. You can\n   use `garn edit` to start a text editor.\n\n   Check out the [getting started guide](https://garn.io/docs/getting_started) for\n   more information on how to write and modify your `garn.ts` file.\n\n3) **Run some things**: Use the **garn** [commands](#commands) to run some\n   tests, build packages, or run executables.\n\n## Commands\n\n### `garn init`\n\nRunning `garn init` in a directory without a `garn.ts` file will try to\nautomatically detect what kind of project you have and generate a `garn.ts`\nfile for you.\n\n### `garn enter`\n\n`garn enter [project or environment]` will put you in a development shell with\nall needed dependencies available in your `$PATH`.\n\n### `garn build`\n\n`garn build [project]` will build the specified project and create a symlink\nnamed `result` which links to the resulting build artifacts.\n\n### `garn run`\n\n`garn run [project]` will run the default executable for the specified project.\n\n### `garn check`\n\n`garn check [check]` will run all checks for the specified project. These\nchecks run in a sandbox. The downside of sandboxing is that these checks won't\nhave access to the internet. The upside is that they'll be (almost) perfectly\nreproducible.\n\n### `garn edit`\n\n`garn edit` will start (and, if necessary, download) VSCodium, with Deno LSP\nconfigured for you. It will open `garn.ts` in the current directory. This won't\nclobber any of your existing VSCode/VSCodium configuration and data.\n\n## Core concepts\n\n* **Environments** (also known as devshells, devenvs, virtualenvs) are the context in which a command runs. That includes: packages that are installed, shell variables that are set, PATH elements. Used both for a devshell experience (think Python virtualenvs) and for giving context to `Executable`s.\n* **Packages** are recipes for building artifacts (such as binaries or JS bundles). These recipes run in an isolated environment. They also refer to the artifacts themselves.\n* **Checks** are like `Package`s, but where we don't care about the artifacts as much as the exit code.\n* **Executables** are what you already know: bash scripts or binaries that you can run. They have their own `Environment`, so often can rely on dependencies that are not available \"outside\".\n* **Projects** are collections of the above.\n* **Plugins** are functions that add functionality to a Project, potentially modifying existing `Checks`, `Packages`, `Executable`s and `Environment`s, or just adding new ones.\n\n\n## Languages and Stacks\n\n  \u003cimg src=\"./lingua-franca.png\"\u003e\n\n\u003cbr/\u003e\n\u003cbr/\u003e\n\nWe currently have support for the Npm, Yarn, Go, and Haskell projects, with\nmore languages coming soon. If you really want to see something, make your\nvoice heard in our issue tracker!\n\nNote also our [examples](https://github.com/garnix-io/garn/tree/main/examples)\ndirectory, which contains tested examples of using **garn** in various ways.\n\nAll examples below require the two following imports:\n\n```typescript\nimport * as garn from \"https://garn.io/ts/v0.0.20/mod.ts\";\nimport * as pkgs from \"https://garn.io/ts/v0.0.20/nixpkgs.ts\";\n```\n\nAll `garn.ts` files require the first import, and often you also need the\nsecond. Besides that, you rarely need other imports.\n\n### Npm\n\nThe basic workhorse of Npm projects is `mkNpmProject`. An example:\n\n```typescript\nexport const frontend = garn.javascript.mkNpmProject({\n  description: \"My project frontend\",\n  src: \".\",\n  nodeVersion: \"18\",\n})\n  .withDevTools([pkgs.jq])\n  .addExecutable(\"run\", \"npm install \u0026\u0026 npm start\")\n  .addCheck(\"test\", \"npm install \u0026\u0026 npm run test\");\n```\n\nThis creates a Project containing:\n\n- A reproducible, CI-ready Check (run it with `garn check frontend.test`)\n- A no-installation-needed Executable (run it with `garn check frontend.test`).\n- An Environment or devshell you can enter with `garn enter frontend` with all\n  dependencies available.\n\nThe right version of `node`, `npm`, `jq`, etc. will be used for all these.\nYou can see a full project [here](https://github.com/garnix-io/garn/tree/main/examples/npm-project).\n\n### Go\n\nGo projects are usually built with `mkGoProject`:\n\n```typescript\nexport const server = garn.go.mkGoProject({\n    description: \"example backend server in go\",\n    src: \".\",\n    goVersion: \"1.21\",\n  })\n  .addExecutable(\"migrate\", \"go run ./scripts/migrate.go\")\n  .addExecutable(\"dev\", \"go run ./main.go\");\n```\n\n### Haskell\n\nFor creating Haskell projects, there's `mkHaskellProject`. An example:\n\n```typescript\nexport const project = garn.haskell.mkHaskellProject({\n  description: \"My project\",\n  src: \".\",\n  executables: [\"server\", \"openapi-generation\"]\n  ghcVersion: \"ghc94\"\n})\n```\n\nAssuming you have a `cabal` file in `.`, this creates a Project containing:\n\n- A reproducible, CI-ready Package (run it with `garn build project`) that\n  includes the test-suites of your project.\n- Two executables, that run the corresponding executables from the cabal file.\n  Run them with `garn run project.server` and `garn run project.openapi-generation`.\n- An Environment or devshell you can enter with `garn enter project` with all\n  dependencies available.\n\nThe right version of `node`, `npm`, `jq`, etc. will be used for all these.\nYou can see a full project [here](https://github.com/garnix-io/garn/tree/main/examples/npm-project).\n\n## How it works\n\nThe essential idea is to generate Nix code corresponding to your projects, and\nthen run Nix behind the scenes. In [here](https://github.com/garnix-io/garn/blob/main/ts/nix.ts),\nyou can see the simple but low-level Nix AST we use. Objects such as `Check`s\nhave a `nixExpression` field that contains their corresponding Nix expression.\n\n**garn** then generates a `flake.nix` that, for every exported variable of the `garn.ts` file,\nhas a corresponding `package`, `check`, `devshell` or `app`.\n\nThis means that **garn** integrates with Nix (and the Nix ecosystem) *both ways*:\nyou can write pure Nix expressions and embed them in `garn.ts` files, or import Nix projects, but\nyou can also from Nix call things generated by **garn**.\n\n## Typescript API\n\nYou can find documentation for the **garn** Deno library [here](https://doc.deno.land/https://garn.io/ts/v0.0.20/mod.ts).\n\n\n## Comparison to other tools\n\n- **Nix**: Nix is a brilliant idea with an immense amount of volunteer effort\n  behind it, and the giant's shoulders on which **garn** stands. It has a rather\n  complex CLI, and the Nix language is a whole new thing to learn. That said\n  it is a much more mature project with support for just about every imaginable\n  stack. For complex projects, you might be better off picking Nix right now.\n  For simpler ones, or ones that include collaborators who don't feel comfortable\n  with Nix, **garn** might be a better option.\n\n  But the choice isn't exclusive\n  or binary: **garn** both allows including\n  Nix expressions or dependencies within it, and generates a `flake.nix` file that\n  can be consumed by other Nix expressions, so that you can combine Nix and\n  **garn** quite well.\n- **just**, **taskfile**, and **make**: These are build tools or command runners\n  that help you write and organize the scripts or commands of your project.\n  In that regard, they overlap with **garn**.\n  They are much easier to install and get started with than **garn**. But they\n  don't manage packages and environments at all, so every user still needs to\n  figure that out themselves. **garn** also makes it easy to share your \"recipes\"\n  as a library. (make also does incremental builds, which **garn** does not.)\n- **virtualenv**, **rvm**, **nvm**, etc.: These are *language-specific* tools;\n  very helpful if you need a particular python package or version of python,\n  not at all if you need a system package.\n- **devbox** and **devenv**: Both of these projects are more mature than **garn**;\n  you are likely to find fewer rough corners with them.\n  Other than that, **garn** differs from them in three major ways: it supports\n  writing your own packages and checks which run in isolated environments (such as CI)\n  and can be cached or consumed by downstream users; it allows configuration in\n  Typescript rather than YAML and/or Nix; and it allows easily writing and importing\n  libraries with reusable functionality.\n- **docker**: Docker isolates processes, and is often used to distribute dev\n  environments. **garn** overlaps with this feature. Both tools make it relatively certain that if it works once\n  it works everywhere. But with Docker that comes at the price of harder\n  integration with your development process.\n\n  Besides development environments, Docker is also used for other purposes, such\n  as deployment. **garn** does not support any of that (yet).\n\n\n[^1]: This might not always be true between different architectures and\n  platforms (e.g. Linux vs. MacOS).\n[^2]: That said, the installation of **garn** itself isn't always smooth on MacOS.\n  If you encounter a problem, please [let us know](https://github.com/garnix-io/garn/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarnix-io%2Fgarn","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgarnix-io%2Fgarn","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgarnix-io%2Fgarn/lists"}