Running ClojureScript Apps on Heroku
In this article, you’ll create a simple ClojureScript application with Leiningen, Figwheel, Om and a few other libraries from the Chestnut template. Then you’ll learn how to deploy that application as an Uberjar to Heroku.
Creating a ClojureScript app
The simplest way to create a new ClojureScript app is by using a template such as Chestnut. Chestnut builds a barebones app that is prepared for development with a browser-connected REPL and instant reloading of Clojure, ClojureScript, and CSS. But it also has all of the configuration you need to deploy that same app to production.
To create a new Chestnut application, run this command:
Then move into the app directory by running:
Now you can run the application locally from a REPL. First, start the REPL by running this command:
When the REPL is ready, execute the (run)
function to start the app:
After you see the Successfully compiled ...
message, open a browser to http://localhost:10555
, and you’ll see the “Hello Chestnut” text.
Preparing for Production
The Chestnut template is already prepared for Heroku deployment. In this section, we’ll describe how it’s configure so that you can use a similar pattern in your own application if you didn’t start with Chestnut.
When you deploy a Clojure or ClojureScript application to Heroku, the platform detects if your application is configured to be built as a Uberjar. You may be using Figwheel in development, but in most cases you will want the robustness of a Jetty or HttpKit backed Uberjar for deployment.
A Chestnut application will contain this line in it’s project.clj
:
It also contains a profile that configures how the Uberjar will package up the Clojure and ClojureScript code:
The main entry point of the Uberjar is my-app.server
, which is a file that was generated by Chestnut. This file contains a main
function that boots Ring and Jetty, which provide an HTTP server for the static content compiled from your ClojureScript code. This is especially convenient because in most cases you’ll eventually need some server-side logic, which you can easily add to the project.
Before you deploy, try building the Uberjar locally:
And run it with this command:
The heroku local
command reads the web
command from the application’s Procfile
. This file is preconfigured by Chestnut with the following content:
You’ll need to add a similar file to a non-Chestnut app before deploying.
Open a browser to http://localhost:5000
and you’ll see the “Hello Chestnut” text again. Then kill the server by pressing Ctrl+C.
Deploying to Heroku
Before you can deploy to Heroku, you’ll need to create a free Heroku account and install the Heroku toolbelt. Then log into the toolbelt CLI with the account you created by running:
Next, initialize a local Git repository for your application by running these commands:
Now create a Heroku application for your project by running this command:
This will provision a new remote Git repository on the Heroku servers, and add it as a remote to your local repo. To deploy, you push to the remote Git just as you might push to a Github repo by running this command:
After some time, your app with be up and running. You can check it’s status with the heroku ps
command, and you can view it’s logs with the heroku logs
command. To view the app in a browser, run this command:
Pushing Local Changes
Now let’s make some changes to the application and push those up to Heroku.
Open the file src/cljs/my_app/core.cljs
. It looks like this:
As you can see, it’s using Om, a ClojureScript interface to Facebook’s React. Let’s change this simple view so that it renders a list of contact. In the spirit of Clojure, you’ll use REPL-driven development as you do this. Before starting you’re REPL, you need to clean the Uberjar artifacts by running this command (otherwise you’ll get a “Production environment code is being loaded while the dev environment is active” error).
Now start your REPL again and boot the app with (run)
. In the src/cljs/my_app/core.cljs
file, replace the app-state
definition with this code:
Then add these functions after the app-state definition:
Finally, replace the main
function with this:
Then view your app in the browser and you’ll see the list of contact.
Now you can deploy these changes to Heroku with just a few commands. Kill the REPL or open a new terminal and run this:
In just a few moments you app with be deployed and you can view it again with heroku open
.
This is just a very simply introduction to Om and ClojureScript. You can learn a great deal more about unlocking their potential in the Om tutorial.
Further Reading
Here are some articles on Heroku’s Clojure support:
- Deploying Clojure Apps on Heroku
- Heroku Clojure Support
- Deploying Clojure Applications with the Heroku Leiningen Plugin
- Deploying Clojure Apps to Heroku with Docker
Here some great resources for learning more about ClojureScript.