Using Node.js with Clojure and ClojureScript Applications
Last updated May 27, 2020
Many Clojure and ClojureScript applications need a Node.js runtime during the build process or even to run an app. This article describes a few different ways in which Node.js can be combined with an application that uses the Clojure buildpack.
If you are new to Clojure or ClojureScript and want to create an app from scratch, you should start with a framework like Luminus or Chestnut to generate a template for you. Both of these frameworks generate the necessary configuration for Heroku. This guide is primarily for developers who are trying to configure an existing app to build and run on Heroku.
Using multiple buildpacks
The Node.js buildpack can be combined with the Clojure buildpack using Heroku’s multi-buildpack support. This is useful for apps that contain a package.json
file and need to run npm
to manage dependencies. You can combine buildpacks by running the following commands:
$ heroku buildpacks:clear
$ heroku buildpacks:add heroku/nodejs
$ heroku buildpacks:add heroku/clojure
Then confirm the execution order by running this command:
$ heroku buildpacks
=== nameless-brushlands-4859 Buildpack
1. heroku/nodejs
2. heroku/clojure
This ensures Heroku will run the Node.js buildpack first, and the Clojure buildpack second.
In order for the Node.js buildpack to execute, your project must also have a package.json
file. In this file, you can define the version of Node.js to install and any dependencies your app needs. Create the package.json
file in the root of your project and put the following code in it:
{ "engines": { "node": "4.0.0" } }
You can also leave it empty (i.e. {}
) to always pick up the latest version.
Then add the file to your Git repository by running the following commands:
$ git add package.json
$ git commit -m "Added package.json"
Upon your next deployment, Heroku will run the Node.js buildpack first, which will install the Node.js runtime and NPM. Then NPM will install any dependencies you have in your package.json
.
Using lein-npm
The lein-npm plugin is a popular Leiningen plugin that supports NPM configuration directly in the project.clj
file. An app that uses lein-npm will not have a package.json
file, and cannot depend on the Node.js buildpack to manage dependencies.
Fortunately, the Clojure buildpack can detect the use of lein-npm, and will install a Node.js runtime if the plugin is found. Then it will add the deps
target to your Leiningen buildpack process to ensure that all NPM packages are installed.
No additional configuration is required when using lein-npm. However, you can set the Node.js version with the following configuration variable:
$ heroku config:set NODEJS_VERSION=4.2.1
If you need this behavior but are not using lein-npm, you can force the Clojure buildpack to install Node.js by setting the NODEJS_VERSION
config variable described above. If you need to disable this behavior, you can set the following config variable:
$ heroku config:set SKIP_NODEJS_INSTALL=true
Here is a sample ClojureScript application using lein-npm. An application of this type can then be run with a JVM-based server such as Jetty, or it can be run on Node.js itself.
Using Node.js to run ClojureScript apps
To run a ClojureScript app on Node.js, you must first have a Node.js runtime installed via either of the two methods described above.
Then you must configure your application’s :cljsbuild
directive to compile for the :nodejs
target. Here is an example of what this might look like in your project.clj
:
:cljsbuild {
:builds [{
:source-paths ["src/myexample"]
:compiler {:output-to "target/js/myexample.js"
:target :nodejs
:optimizations :simple }}]})
Then you must configure your Procfile
to use the node
command to run your Javascript. For example:
web: node target/js/myexample.js
A complete example can be found in this sample ClojureScript application that runs on Node.js.