{"id":13442451,"url":"https://github.com/boot-clj/boot","last_synced_at":"2025-05-14T07:08:11.523Z","repository":{"id":22321447,"uuid":"25656802","full_name":"boot-clj/boot","owner":"boot-clj","description":"Build tooling for Clojure.","archived":false,"fork":false,"pushed_at":"2021-04-22T20:43:31.000Z","size":3062,"stargazers_count":1748,"open_issues_count":111,"forks_count":179,"subscribers_count":55,"default_branch":"master","last_synced_at":"2025-05-08T20:24:15.413Z","etag":null,"topics":["boot","boot-clj","build-tool","clojure"],"latest_commit_sha":null,"homepage":"https://boot-clj.github.io/","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/boot-clj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"open_collective":"boot-clj"}},"created_at":"2014-10-23T20:36:42.000Z","updated_at":"2025-05-08T01:18:41.000Z","dependencies_parsed_at":"2022-08-20T07:31:19.803Z","dependency_job_id":null,"html_url":"https://github.com/boot-clj/boot","commit_stats":null,"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boot-clj%2Fboot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boot-clj%2Fboot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boot-clj%2Fboot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/boot-clj%2Fboot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/boot-clj","download_url":"https://codeload.github.com/boot-clj/boot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253884989,"owners_count":21978778,"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":["boot","boot-clj","build-tool","clojure"],"created_at":"2024-07-31T03:01:45.870Z","updated_at":"2025-05-14T07:08:11.505Z","avatar_url":"https://github.com/boot-clj.png","language":"Clojure","readme":"\u003ca href=\"http://boot-clj.com/\"\u003e\n  \u003cimg src=\"http://boot-clj.com/assets/images/logos/boot-logo-3.png\" alt=\"Boot Logo\" title=\"Boot\" align=\"right\" width=\"225px\" /\u003e\n\u003c/a\u003e\n\n# Boot \n\n[![Build Status](https://travis-ci.org/boot-clj/boot.svg?branch=master)](https://travis-ci.org/boot-clj/boot) [![Stories in Ready][waffle-badge]][waffle-board] [![Backers on Open Collective](https://opencollective.com/boot-clj/backers/badge.svg)](#backers)\n [![Sponsors on Open Collective](https://opencollective.com/boot-clj/sponsors/badge.svg)](#sponsors) \n\n[change log][changes] | [installation][4] | [getting started][start] | [documentation][wiki] | [API docs][api-docs]\n\nBoot is a Clojure build framework and ad-hoc Clojure script evaluator. Boot\nprovides a runtime environment that includes all of the tools needed to build\nClojure projects from scripts written in Clojure that run in the context of\nthe project.\n\n\u003e If you have questions or need help, please [visit the Discourse site][discourse].\n\u003e You can find other developers and users in [the `#boot` channel on Clojurians Slack][slack].\n\n### Another Build Tool?\n\nBuild processes for applications always end up being complex things. A\nsimple web application, for instance, may require many\nintegrations–asset pipelines, deployment to different environments,\nthe compilation of multiple artifacts with different compilers,\npackaging, etc.\n\nThe more complex the build process becomes, the more flexible the build tool\nneeds to be. Static build specifications become less and less useful as the\nproject moves toward completion. Being Lispers we know what to do: Lambda is\nthe ultimate declarative.\n\nInstead of building the project based on a global configuration map, boot\nprovides a runtime environment in which a build script written in Clojure\ncan be evaluated. It is this script\u0026mdash;a Turing-complete build\nspecification\u0026mdash;which builds the project.\n\n### Features\n\n* Write executable, self-contained scripts in Clojure and run them with or\n  without a project context.\n* Dynamically add dependencies from Maven repositories to the running script's\n  class path.\n* Managed filesystem tree provides a scoped, immutable, append-only interface.\n* Fine-grained control of classloader isolation–run code in separate Clojure\n  runtimes.\n* Tasks are functions that return middleware which compose to form build\n  pipelines.\n* Tasks are not coupled via hardcoded file paths or magical keys in a global\n  configuration map.\n* Create new, ad-hoc tasks easily in the project, in the build script, or in\n  the REPL.\n* Compose build pipelines in the project, in the build script, in the REPL, or\n  on the command line.\n* Artifacts can never be stale–there is no need for a `clean` task.\n\n## Install\n\nBinaries in executable format are available. Follow the instructions for your\noperating system (note: boot requires the Java Development Kit (JDK) version\n1.8 or greater).\n\n#### Unix, Linux, OSX\n\nPackage managers:\n\n* [Homebrew][brew] \u0026mdash; `brew install boot-clj`\n* [nix](http://nixos.org/nix) \u0026mdash; `nix-env -i boot`\n* [aur](https://aur.archlinux.org) \u0026mdash; `yaourt --noconfirm -Syy boot`\n* [docker](https://www.docker.com/) \u0026mdash; Use [`clojure`](https://hub.docker.com/_/clojure/) image with `boot` tag.\n    - CircleCI also maintains image with [additional tooling](https://circleci.com/docs/2.0/circleci-images/): [`circleci/clojure`](https://hub.docker.com/r/circleci/clojure/)\n\nOtherwise:\n\n* Download [boot.sh][boot-sh] and save as `boot`\n* Make it executable.\n* Move it to somewhere in your `$PATH`.\n\nHere is a one-liner to do the above:\n\n```sh\n$ sudo bash -c \"cd /usr/local/bin \u0026\u0026 curl -fsSLo boot https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh \u0026\u0026 chmod 755 boot\"\n```\n\n#### Windows\n\nPackage managers:\n\n* [Chocolatey](https://chocolatey.org/) \u0026mdash; `choco install boot-clj`\n* [Scoop](http://scoop.sh/) \u0026mdash; `scoop bucket add extras \u0026\u0026 scoop install boot-clj`\n\nOtherwise, download [boot.exe][boot-exe], then:\n\n```bat\n:: Using %SystemRoot% here, but can be any folder on user's %PATH%\nC:\\\u003e move boot.exe %SystemRoot%\n```\n\n\u003e **Note:** Windows 10 is fully supported. For other versions please see\n\u003e [these outstanding issues][win-issues] for specific limitations.\n\n## Update\n\nThe boot.sh/boot.exe wrapper is a very thin shim used to load \"the real Boot\"\nfrom Maven. With the wrapper installed you can update Boot's JAR files and\nkeep up to date with the following command:\n\n    boot -u\n\nThe boot.sh/boot.exe wrapper itself changes (and thus requires updating) much\nless frequently, and will remain compatible with future versions of the JAR\nfiles.\n\n## Getting Started\n\n\u003e The [Modern CLJS](https://github.com/magomimmo/modern-cljs) tutorials are an\n\u003e excellent introduction to Boot and ClojureScript. Pretty much everything you\n\u003e need to know about Boot to get a project off the ground is covered there.\n\u003e Check it out!\n\nOnce boot is installed (see [Install][4] above) do this in a terminal:\n\n    boot -h\n\nYou should see the boot manual page printed to the terminal. This information\nincludes command line options recognized by boot, a list of available tasks,\nand other information about relevant configuration files and environment\nvariables.\n\nYou can also get help for a specific task, for example the `repl` task:\n\n    boot repl -h\n\nYou should see usage info and command line options for the specified task.\n\n### Task Help in the REPL\n\nYou can also get help in the REPL. First start a REPL session:\n\n    boot repl\n\nThen, to get help for the `repl` task, do:\n\n```clojure\nboot.user=\u003e (doc repl)\n```\n\nThe output will be slightly different from the command line help info. We'll see\nwhy this is so a little later.\n\n### Build From the Command Line\n\nLet's build a simple project to get our feet wet. We'll create a new directory,\nsay `my-project`, and a source directory in there named `src` with a source\nfile, `hello.txt`:\n\n    mkdir -p my-project/src\n    cd my-project\n    echo \"hi there\" \u003e src/hello.txt\n\nThe directory should now have the following structure:\n\n    my-project\n    └── src\n        └── hello.txt\n\nSuppose we want to build a jar file now, and install it to our local Maven\nrepository. We'll use the `pom`, `jar`, and `install` tasks to accomplish this\nfrom the command line:\n\n```bash\n# The -- args below are optional. We use them here to visually separate the tasks.\nboot -r src -d me.raynes/conch:0.8.0 -- pom -p my-project -v 0.1.0 -- jar -M Foo=bar -- install\n```\n\nWhat we did here was we built a pipeline on the command line and ran it to\nbuild our project. \n\n* We specified the resource directory (files that will end up in the jar) via boot's `-r` option.\n* We added the `conch` dependency via boot's `-d` option.\n\nThis sets up the build environment. Then we constructed a pipeline of tasks:\n\n* The `pom` task with options to set the project ID and version,\n  (by default only compiled artifacts end up in the fileset),\n* The `jar` task with options to add a `Foo` key to the jar,\nmanifest with value `bar`,\n* And finally the `install` task with no options.\n\nBoot composes the pipeline and runs it, building your project. Your local\nMaven repository will now contain `my-project-0.1.0.jar`.\n\n### Build From the REPL\n\nAnything done on the command line can be done in the REPL or in a build script.\nFire up a REPL in the project directory:\n\n    boot repl\n\nThe default namespace is `boot.user`, which is the namespace given to the build\nscript. Building the project in the REPL is almost identical to what we did on\nthe command line.\n\nFirst we'll set some global boot options–we'll set the source directory and add\nthe `conch` dependency to the build environment:\n\n```clojure\nboot.user=\u003e (set-env! \n       #_=\u003e   :resource-paths #{\"src\"}\n       #_=\u003e   :dependencies '[[me.raynes/conch \"0.8.0\"]])\n```\n\nThis was specified on the command line as the `-r` or `--resource-paths` and `-d` or\n`--dependencies` arguments to boot itself. These translate to calls to `set-env!`\nin the REPL or in a script. Note that the keyword always corresponds to the long\noption from the command line.\n\nNow that boot environment is set up we can build the project:\n\n```clojure\nboot.user=\u003e (boot (pom :project 'my-project :version \"0.1.0\")\n       #_=\u003e       (jar :manifest {\"Foo\" \"bar\"})\n       #_=\u003e       (install))\n```\n\nAgain, note that the keyword arguments correspond to long options from the\ncommand line.\n\n### Configure Task Options\n\nIt gets tedious to specify all of those options on the command line or in the\nREPL every time you build your project. Boot provides facilities for setting\ntask options globally, with the ability to override them by providing options\non the command line or in the REPL later.\n\nThe `task-options!` macro does this. Continuing in the REPL:\n\n```clojure\nboot.user=\u003e (task-options!\n       #_=\u003e   pom {:project 'my-project\n       #_=\u003e        :version \"0.1.0\"}\n       #_=\u003e   jar {:manifest {\"Foo\" \"bar\"}})\n```\n\nNow we can build the project without specifying these options, because the\ntask functions have been replaced with curried versions of themselves:\n\n```clojure\nboot.user=\u003e (boot (pom) (jar) (install))\n```\n\nIndividual options can still be set by providing arguments to the tasks such\nthat they override those set with `task-options!`. Let's build our project with\na different version number, for example:\n\n```clojure\nboot.user=\u003e (boot (pom :version \"0.1.1\") (jar) (install))\n```\n\nPretty simple, right? This way of setting options requires no participation by\nthe tasks themselves. There is no global configuration map or anything like\nthat. It works because tasks accept only [keyword arguments][9], so partial\napplication is idempotent and last setting wins.\n\n### Write a Build Script\n\nMore sophisticated builds will require one, but even a build as simple as this\none can be made a little simpler by creating a build script containing the\noptions for the tasks you're using.\n\nCreate a file named `build.boot` in the project directory with the following\ncontents:\n\n```clojure\n(set-env!\n  :resource-paths #{\"src\"}\n  :dependencies '[[me.raynes/conch \"0.8.0\"]])\n\n(task-options!\n  pom {:project 'my-project\n       :version \"0.1.0\"}\n  jar {:manifest {\"Foo\" \"bar\"}})\n```\n\nNow we can build the project without specifying the options for each task on\nthe command line–we only need to specify the tasks to create the pipeline.\n\n    boot pom jar install\n\nAnd we can override these options on the command line as we did in the REPL:\n\n    boot -- pom -v 0.1.1 -- jar -- install\n\nNotice how we did not need a `(boot ...)` expression in the `build.boot` script.\nBoot constructs that at runtime from the command line arguments.\n\nYou can start a REPL in the context of the boot script (compiled as the\n`boot.user` namespace), and build interactively too:\n\n```clojure\nboot.user=\u003e (boot (pom) (jar) (install))\n```\n\nWhen boot is run from the command line it actually generates a `boot` expression\naccording to the command line options provided.\n\n### Define a Task\n\nCustom tasks can be defined in the project or in `build.boot`. This is generally\nhow boot is expected to be used, in fact. Boot ships with a selection of small\ntasks that can be composed uniformly, and the user assembles them into something\nthat makes sense for the specific project.\n\nAs an example let's make a task that performs the last example above, and name\nit `build`. We'll modify `build.boot` such that it contains the following:\n\n```clojure\n(set-env!\n  :resource-paths #{\"src\"}\n  :dependencies '[[me.raynes/conch \"0.8.0\"]])\n\n(task-options!\n  pom {:project 'my-project\n       :version \"0.1.0\"}\n  jar {:manifest {\"Foo\" \"bar\"}})\n\n(deftask build\n  \"Build my project.\"\n  []\n  (comp (pom) (jar) (install)))\n```\n`NOTE: When using comp, all arguments must be functions - nil is not supported.\nIn this example we call each task middleware which returns the task function, these functions are composed into a new build task.`\n\nNow we should be able to see the `build` task listed among the available tasks\nin the output of `boot -h`, and we can run the task from the command line as we\nwould run any other task:\n\n    boot build\n\nTasks are functions that return pipelines. Pipelines compose functionally to\nproduce new pipelines. If you've used [transducers][7] or [ring middleware][8]\nthis pattern should be familiar. The `pom` and `install` functions we used in\nthe definition of `build` are, in fact, the same functions that were called\nwhen we used them on the command line before. Boot's command line parsing\nimplicitly composes them; in our task we compose them using Clojure's `comp`\nfunction.\n\n### Define Tasks In Project\n\nNow let's define a task in a namespace in our project and use it from the\ncommand line.\n\nCreate the namespace with the task:\n\n```clojure\n(ns demo.boot-build\n  (:require [boot.core :as core]\n            [boot.task.built-in :as task]))\n\n(core/deftask build\n  \"Build my project.\"\n  []\n  (comp (task/pom) (task/jar) (task/install)))\n```\n\nand write it to `src/demo/boot_build.clj` in your project.\n\nModify the `build.boot` file to incorporate this new task by removing the\ndefinition for `build`. The new `build.boot` file will look like this:\n\n```clojure\n(set-env!\n  :resource-paths #{\"src\"}\n  :dependencies '[[me.raynes/conch \"0.8.0\"]])\n\n(task-options!\n  pom {:project 'my-project\n       :version \"0.1.0\"}\n  jar {:manifest {\"Foo\" \"bar\"}})\n\n(require '[demo.boot-build :refer :all])\n```\n\nYou can now use the `build` task defined in the project namespace from the\ncommand line, as before:\n\n    boot build\n\n...\n\n## Hacking Boot\n\nTo build boot from source you will need:\n\n* JDK 1.8\n* GNU make\n* maven 3\n* bash shell, wget\n* [boot.sh][boot-sh] (Unix) or [boot.exe][boot-exe] (Windows)\n\nYou may increment Boot's version by editing `version.properties`:\n\n```properties\n# \u003cversion\u003e is the version of your build\nversion=\u003cversion\u003e\n```\n\nThen, in a terminal in the project directory do:\n\n    make deps\n    make install\n\n- Jars for all of the boot components will be built and installed in your\n  local Maven repository.\n- The app uberjar will be built and copied to `bin/boot.jar`.\n- The app uberjar will be copied to `$HOME/.boot/cache/bin/\u003cversion\u003e/boot.jar`.\n\nMake your build the default by editing your `$HOME/.boot/boot.properties` file:\n\n```properties\n# \u003cversion\u003e is the version of your build\nBOOT_VERSION=\u003cversion\u003e\n```\n\nFor guidelines for contributing, see [CONTRIBUTING.md](CONTRIBUTING.md).\n\n## Attribution\n\nCode from other projects was incorporated into boot wherever necessary to\neliminate external dependencies of boot itself. This ensures that the project\nclasspath remains pristine and free from potential dependency conflicts. We've\npulled in code from the following projects (thanks, guys!)\n\n* [technomancy/leiningen][50]\n* [cemerick/pomegranate][51]\n* [Raynes/conch][52]\n* [tebeka/clj-digest][53]\n* [cldwalker/table][54]\n* [clojure/tools.cli][55]\n* [bbloom/backtick][56]\n* [AvisoNovate/pretty][57]\n* google/hesokuri\n* [barbarysoftware/watchservice][58]\n\nThe boot source is also annotated to provide attribution wherever possible.\nLook for the `:boot/from` key in metadata attached to vars or namespaces.\n\n## Contributors\n\nThis project exists thanks to all the people who contribute. [[Contribute](CONTRIBUTING.md)].\n\u003ca href=\"https://github.com/boot-clj/boot/graphs/contributors\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/contributors.svg?width=890\u0026button=false\" /\u003e\u003c/a\u003e\n\n\n## Backers\n\nThank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/boot-clj#backer)]\n\n\u003ca href=\"https://opencollective.com/boot-clj#backers\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/backers.svg?width=890\"\u003e\u003c/a\u003e\n\n\n## Sponsors\n\nSupport this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/boot-clj#sponsor)]\n\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/0/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/0/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/1/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/1/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/2/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/2/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/3/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/3/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/4/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/4/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/5/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/5/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/6/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/6/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/7/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/7/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/8/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/8/avatar.svg\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opencollective.com/boot-clj/sponsor/9/website\" target=\"_blank\"\u003e\u003cimg src=\"https://opencollective.com/boot-clj/sponsor/9/avatar.svg\"\u003e\u003c/a\u003e\n\n\n\n## License\n\nCopyright © 2013-2018 Alan Dipert and Micha Niskin\n\nDistributed under the Eclipse Public License, the same as Clojure.\n\n[boot-sh]: https://github.com/boot-clj/boot-bin/releases/download/latest/boot.sh\n[boot-exe]: https://github.com/boot-clj/boot-bin/releases/download/latest/boot.exe\n[4]: #install\n[5]: https://drone.io/github.com/boot-clj/boot/status.png?camocache=1\n[6]: https://drone.io/github.com/boot-clj/boot/latest\n[7]: http://clojure.org/transducers\n[8]: http://drtom.ch/posts/2012-12-10/An_Introduction_to_Webprogramming_in_Clojure_-_Ring_and_Middleware/#ring-middleware\n[9]: https://clojurefun.wordpress.com/2012/08/13/keyword-arguments-in-clojure/comment-page-1/\n\n[20]: doc/clojure-scripting-with-boot.md\n[21]: doc/overview-of-the-boot-workflow.md\n[22]: doc/boot-task-writers-guide.md\n[23]: https://boot-clj.github.io/boot\n[24]: doc/boot-clojure-version-howto.md\n[25]: https://github.com/boot-clj/boot/wiki\n\n[50]: https://github.com/technomancy/leiningen\n[51]: https://github.com/cemerick/pomegranate\n[52]: https://github.com/Raynes/conch\n[53]: https://github.com/tebeka/clj-digest\n[54]: https://github.com/cldwalker/table\n[55]: https://github.com/clojure/tools.cli\n[56]: https://github.com/brandonbloom/backtick\n[57]: https://github.com/AvisoNovate/pretty\n[58]: https://code.google.com/p/barbarywatchservice/\n\n[l4j]: http://sourceforge.net/projects/launch4j/files/launch4j-3/3.8/\n[waffle-badge]: https://badge.waffle.io/boot-clj/boot.svg?label=ready\u0026title=Ready\n[waffle-board]: http://waffle.io/boot-clj/boot\n[discourse]: https://clojureverse.org/c/projects/boot\n[irc]: http://webchat.freenode.net/?channels=bootclj\n[slack]: http://clojurians.net/\n[changes]: https://github.com/boot-clj/boot/blob/master/CHANGES.md\n[brew]: https://github.com/homebrew/homebrew\n[win-issues]: https://github.com/boot-clj/boot/issues?q=is%3Aopen+is%3Aissue+label%3Awindows+label%3Ablocked\n[start]: #getting-started\n[wiki]: https://github.com/boot-clj/boot/wiki\n[api-docs]: https://github.com/boot-clj/boot/tree/master/doc\n","funding_links":["https://opencollective.com/boot-clj"],"categories":["Clojure","tools","Build Automation and Package management","构建工具","Tools","Clojure Tools, Libraries, and Frameworks"],"sub_categories":["Mesh networks","JavaScript Libraries for Machine Learning"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboot-clj%2Fboot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fboot-clj%2Fboot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fboot-clj%2Fboot/lists"}