Re-Frame Javascript Interop

Alexander Poole
2 min readFeb 23, 2021

How can we embed native javascript objects into the Re-Frame data loop?

First lets create a Re-Frame app. You’ll need to install Clojure and Leiningen (a build tool) by following these instructions.

To create an application with just the base template, use this command:

$ lein new re-frame example-app

To run our app we can use the following command:

$ lein watch auto

Now we have our very own Re-Frame App running on http://localhost:8020 go and take a look!

To answer this lets first look at how we can interact with Javascript from Clojurescript:

Let us start with creating a Javascript library that we can play with. Here is a basic library https://github.com/owodunni/exampleModule.

It exports some functions that will print to the log. That is handy in order to see that we are interacting with Javascript correctly.

Go ahead and install it to our Re-Frame App using:

$ npm install git+https://github.com/owodunni/exampleModule.git

We can try and use our example module from events.cljs in the following way:

(ns example-app.events
(:require
[re-frame.core :as re-frame]
[example-app.db :as db]
[examplemodule :as ex]
))
(re-frame/reg-event-db
::initialize-db
(fn [_ _]
(ex/logFunc "Hello from JS!")
db/default-db))

This will print a nice little greeting in our log!

How about adding a callback to a Javascript function? We can modify our code above:

(re-frame/reg-event-db
::initialize-db
(fn [_ _]
(ex/logAndCallbackFunc
"Hello from Javascript!"
(fn [] (prn "Hello from Clojurescript!")))
db/default-db))

This will give us two messages one printed in Javascript and one printed in Clojurescript.

Finally we can create a object and call its function. Hed over to db.cljs there we have our default-db lets add our logger to it:

(ns example-app.db
(:require
[examplemodule :as ex]))
(def default-db
{:name "re-frame"
:logger (ex/Logger. "Almighty logger")})

We can now use our logger wherever we have access to our db lets use it in subs.cljs:

(ns example-app.subs
(:require
[re-frame.core :as re-frame]))
(re-frame/reg-sub
::name
(fn [db]
(.log (get db :logger) "calling from reg-sub")
(:name db)))

We will now have a new greeting waiting for us in the console!

Thats it! I hope that helped someone get a hang of Javascript Clojurescript interop.

--

--