{"id":13569185,"url":"https://github.com/gbaptista/fnx","last_synced_at":"2025-04-08T17:33:19.854Z","repository":{"id":41502712,"uuid":"435192656","full_name":"gbaptista/fnx","owner":"gbaptista","description":"A package manager for the Fennel language.","archived":false,"fork":false,"pushed_at":"2022-04-03T15:13:49.000Z","size":93,"stargazers_count":28,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-02-14T13:50:29.078Z","etag":null,"topics":["fennel","fnx","package-manager"],"latest_commit_sha":null,"homepage":"https://github.com/gbaptista/fnx","language":"Fennel","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gbaptista.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-12-05T14:40:18.000Z","updated_at":"2025-01-01T18:04:19.000Z","dependencies_parsed_at":"2022-09-02T15:11:51.722Z","dependency_job_id":null,"html_url":"https://github.com/gbaptista/fnx","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbaptista%2Ffnx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbaptista%2Ffnx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbaptista%2Ffnx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gbaptista%2Ffnx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gbaptista","download_url":"https://codeload.github.com/gbaptista/fnx/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247893003,"owners_count":21013819,"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":["fennel","fnx","package-manager"],"created_at":"2024-08-01T14:00:36.812Z","updated_at":"2025-04-08T17:33:19.833Z","avatar_url":"https://github.com/gbaptista.png","language":"Fennel","funding_links":[],"categories":["Fennel","Tools"],"sub_categories":[],"readme":"# fnx\n\nA package manager for the [Fennel](https://fennel-lang.org/) language.\n\n\u003e _**Disclaimer:** It's an early-stage project, and you should expect breaking changes._\n\n![fspec dep list example](https://raw.githubusercontent.com/gbaptista/assets/0f230313d9087dd73926be0e918c407e2342d659/fnx/readme-v2.png)\n\n- [1-liner Installer](#1-liner-installer)\n- [.fnx.fnl File](#fnxfnl-file)\n- [Usage](#usage)\n- [Embedding](#embedding)\n- [Installing](#installing)\n  - [Options](#installation-options)\n  - [Requirements](#requirements)\n- [Performance](#performance)\n- [sudo](#sudo)\n- [Debugging](#debugging)\n  - [Inside Fennel](#inside-fennel)\n- [Development](#development)\n- [Not a Roadmap](#not-a-roadmap)\n\n## 1-liner Installer\n\nYou need to have all [requirements](#requirements) first.\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/gbaptista/fnx/main/get-fnx.sh -o get-fnx.sh \u0026\u0026 sh get-fnx.sh\n```\n\n## `.fnx.fnl` File\n\nThe `.fnx.fnl` file is a regular Fennel source code in the root directory of your project that should return a table.\n\nExample:\n\n```fennel\n{:name    \"my-package\"\n :version \"0.0.1\"\n\n :dependencies {\n   :fspec         {:fennel/local \"../fspec\"}\n\n   :supernova     {:lua/local \"../supernova\"}\n\n   :splah         {:fennel/fnx {:path \"/home/splah\"}}\n\n   :radioactive   {:fennel/fnx {:git/url \"https://git.sr.ht/~me/radioactive\"}}\n   :fireball      {:fennel/fnx {:git/url \"https://github.com/me/fireball.git\"}}\n\n   :moonlight     {:fennel/fnx {:git/sourcehut \"~me/moonlight\" :commit \"a6c728b\"}}\n\n   :meteor        {:fennel/fnx {:git/sourcehut \"~me/meteor\" :branch \"main\"}}\n\n   :jellyfish     {:fennel/fnx {:git/sourcehut \"~me/jellyfish\" :tag \"v0.0.1\"}}\n\n   :purple-rain   {:fennel/fnx {:git/github \"me/purple-rain\"}}\n   :red-sauce     {:fennel/fnx {:git/gitlab \"me/red-sauce\"}}\n   :lemon         {:fennel/fnx {:git/bitbucket \"me/lemon\"}}\n\n   :dkjson        {:lua/rock \"\u003e= 2.5\"}}}\n```\n\n| key | description |\n|-----|-------------|\n| `:name` | Your package name. |\n| `:version` | Your package version. Follows [Semantic Versioning 2.0.0](https://semver.org/) |\n| `:dependencies` | Your package dependencies. The example above should be self explanatory. |\n\n## Usage\n\n\u003e _Try the [Hello World](https://github.com/gbaptista/fnx-hello-world) example._\n\nStart by creating a [.fnx.fnl](#fnxfnl-file) file for your project.\n\n| command \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp;  \u0026nbsp;\u0026nbsp; \u0026nbsp;\u0026nbsp;\u0026nbsp; \u0026nbsp; \u0026nbsp;  \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; \u0026nbsp; | description |\n|---------|-------------|\n| `fnx` | It’s an alias for the `fennel` command that wraps it with `fnx` capabilities. Just use it as a replacement for anything that you would do with `fennel`. It accept any of the options available for the `fennel` command. |\n| `fnx help` | List the available `fnx` commands. |\n| `fnx version` | It returns the `fnx` version. |\n| `fnx config` | It returns the current `fnx` configuration. |\n| `fnx debug` | It returns `fnx` injections for the current directory or file. Use `-b` if you are [embedding](#embedding). |\n| `fnx env` | Generates environment variables exports to make `fnx` [embeddable](#embedding). |\n| `fnx dep` | Dependencies Manager CLI. It lists the available `fnx dep` commands. Its commands accept `--global` and `--local` for `luarocks`. The default is `--local`. |\n| `fnx dep install` | Install the dependencies described in the `.fnx.fnl` file. Use `-f` to force the re-installation of all dependencies. Use `--verbose` for verbose mode. |\n| `fnx dep uninstall` | Uninstall the dependencies described in the `.fnx.fnl` file. Use `-f` to skip confirmation. Use `--verbose` for verbose mode. |\n| `fnx dep list` | It lists the dependencies described in the `.fnx.fnl` file. |\n\n## Embedding\n\nAs is usual for Lua, you may want to embed Fennel into another language, e.g., [_Sweet Moon_](https://github.com/gbaptista/sweet-moon). In this scenario, you wouldn't have direct access to the `fnx` terminal command.\n\nSo, you can run `fnx env` to generate the necessary environment variables:\n```shell\nfnx env\n\nexport FENNEL_PATH=/home/me/.local/share/.fnx/core/?.fnl\nexport FNX_DATA_DIRECTORY=/home/me/.local/share/.fnx/\n```\n\nTo actual export the variables, you can use:\n```sh\neval \"$(fnx env)\"\n```\n\nYou can also add the above line to your `.bashrc`, `.zshrc`, etc.\n\nThen, in your embedded script, you can add:\n```fennel\n(local fnx (require :fnx))\n\n(fnx.bootstrap!)\n```\n\nIt automatically injects all your dependencies according to your `.fnx.fnl` file, similar to using the `fnx` command.\n\nYou may want to set a specific path to the `.fnx.fnl`:\n\n```fennel\n(local fnx (require :fnx))\n\n(fnx.bootstrap! \"/home/me/project/.fnx.fnl\")\n```\n\nAlternative code, for isolation:\n```fennel\n(let [fnx (require :fnx)] (fnx.bootstrap!))\n```\n\nOr, for short:\n```fennel\n((. (require :fnx) :bootstrap!))\n```\n\nIf you need debugging, check [this](#inside-fennel).\n\n## Installing\n\nYou need to have all [requirements](#requirements) first.\n\nCheck the [1-liner Installer](#1-liner-installer) as well.\n\n```sh\ngit clone git@github.com:gbaptista/fnx.git\n\ncd fnx\n\nluarocks install supernova --local\n\nfennel run/install.fnl\n```\n\n### Installation Options\n\nOptions for the `fennel run/install.fnl` command:\n\n| option | description |\n|--------|-------------|\n| `-s` | Use auto-detect information and skip questions. |\n| `-f` | Use auto-detect information and overwrite files without confirmation. |\n| `-d` | Install in development mode as a [symbolic link](https://en.wikipedia.org/wiki/Symbolic_link) for the source code. |\n\n### Requirements\n\n- [Lua](https://www.lua.org/download.html) `5.1` or later.\n- [Fennel](https://fennel-lang.org/setup#downloading-fennel) `1.0.0` or later.\n- [LuaRocks](https://github.com/luarocks/luarocks/wiki/Download)\n- [Git](https://git-scm.com/)\n- [Unix](https://en.wikipedia.org/wiki/Unix)\n  - [`sh`](https://en.wikipedia.org/wiki/Bourne_shell) [`chmod`](https://en.wikipedia.org/wiki/Chmod) `cp` `ln` `ls` `mkdir` `rm`\n\n## Performance\n\nYou might not be happy with the performance of the `fnx` command compared to  `fennel`.\n\nAlternatively, to keep using the `fennel` command, you can do the same configuration used for [embedding](#embedding):\n\nExport the environment variables:\n```sh\neval \"$(fnx env)\"\n```\n\nAdd into your entrypoint source code:\n\n```fennel\n(let [fnx (require :fnx)] (fnx.bootstrap!))\n```\n\nDone. Just run `fennel source.fnl` as usual instead of `fnx source.fnl`.\n\n## sudo\n\nIf you need to use `fnx` with the `sudo` command, you may want to install `fnx` dependencies in the superuser context for a complete experience.\n\nYou can do that with:\n```\nsudo fnx sudo\n```\n\n## Debugging\n\nYou can run `fnx debug` to understand what exactly is being injected:\n```sh\nfnx debug\n```\n\n```\nfspec\n\n--add-package-path /.local/share/.fnx/packages/fspec/default/fspec/?.lua      \n--add-package-path /.local/share/.fnx/packages/fspec/default/?/init.lua       \n                                                                                             \n --add-fennel-path /.local/share/.fnx/packages/fspec/default/fspec/?.fnl      \n --add-fennel-path /.local/share/.fnx/packages/fspec/default/?/init.fnl       \n                                                                                             \n  --add-macro-path /.local/share/.fnx/packages/fspec/default/fspec/?.fnl      \n  --add-macro-path /.local/share/.fnx/packages/fspec/default/?/init-macros.fnl\n  --add-macro-path /.local/share/.fnx/packages/fspec/default/?/init.fnl \n```\n\nIf you are [embedding](#embedding), you can run:\n\n```sh\nfnx debug -b\n```\n\n```\nfspec fspec\n\n     package.path /.local/share/.fnx/packages/fspec/default/fspec/?.lua      \n     package.path /.local/share/.fnx/packages/fspec/default/?/init.lua       \n                                                                                            \n      fennel.path /.local/share/.fnx/packages/fspec/default/fspec/?.fnl      \n      fennel.path /.local/share/.fnx/packages/fspec/default/?/init.fnl       \n                                                                                            \nfennel.macro-path /.local/share/.fnx/packages/fspec/default/fspec/?.fnl      \nfennel.macro-path /.local/share/.fnx/packages/fspec/default/?/init-macros.fnl\nfennel.macro-path /.local/share/.fnx/packages/fspec/default/?/init.fnl\n```\n\n### Inside Fennel\n\n\u003e **Warning:** The `debug` namespace is for debugging only purposes. Its API is unstable and may change anytime. Please don't use it in a way that your project depends on it.\n\nTo debug inside Fennel, you need first to ensure that your environment is ready for [embedding](#embedding).\n\nThen, you can use the `debug` namespace:\n\n```fnl\n(local fnx (require :fnx))\n\n(local fennel (require :fennel))\n\n(print (fennel.view (fnx.debug.injections)))\n; [{:destination \"package.path\"\n;   :package \"fspec\"\n;   :path \"/home/me/.local/share/.fnx/packages/fspec/default/fspec/?.lua\"}\n;  {:destination \"package.path\"\n;   :package \"fspec\"\n;   :path \"/home/me/.local/share/.fnx/packages/fspec/default/?/init.lua\"}\n;  {:destination \"fennel.path\"\n;   :package \"fspec\"\n;   :path \"/home/me/.local/share/.fnx/packages/fspec/default/fspec/?.fnl\"}\n;   ...\n\n(print (fennel.view (fnx.debug.packages)))\n; [{:package \"fspec\"     :language \"fennel\"}\n;  {:package \"supernova\" :language \"lua\"}]\n\n(print (fennel.view (fnx.debug.dot-fnx-path)))\n; \"/home/me/my-project/.fnx.fnl\"\n\n(fnx.bootstrap!)\n```\n\nIf you are using a custom `.fnx.fnl` file:\n\n```fnl\n(local fnx (require :fnx))\n\n(local custom-dot-fnx \"/home/me/some-project/.fnx.fnl\")\n\n(fnx.debug.injections custom-dot-fnx)\n\n(fnx.debug.packages custom-dot-fnx)\n\n(fnx.debug.dot-fnx-path custom-dot-fnx)\n\n(fnx.bootstrap! custom-dot-fnx)\n```\n\n## Development\n\n```\nfnx dep install\nfnx run/test.fnl\n```\n\n## Not a Roadmap\n\nA list of things that I don't have time to do or that just aren't itching me enough to do something about it, but I would like to do it someday, eventually:\n\n- [ ] binaries;\n- [ ] `fnx dep add`;\n- [ ] `fnx dep remove`;\n- [ ] Lock file;\n- [ ] Actually use the version numbers for something;\n- [ ] Improve performance;\n- [ ] Get inspired by [nix](https://nixos.org) to improve the approach;\n- [ ] Provide Windows Support.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbaptista%2Ffnx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgbaptista%2Ffnx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgbaptista%2Ffnx/lists"}