Simpler way to try Respo(virtual DOM in cljs)

To make it even more easier to try Respo, I sorted out this repo, which demonstrates the minimal code to try Respo. https://github.com/Respo/minimal-tiny-app

Respo is a virtual DOM library built in ClojureScript. It’s pure virtual DOM, with no support for side-effects(i.e. no life cycle hooks supported). It’s just purer. Respo is not a replacement for React. However, for apps that can be built with pure virtual DOM, it’s should be quite nice.

Run the demo

To be short, here are the commands you need to run the app:

git clone git@github.com:Respo/minimal-tiny-app.git
cd minimal-tiny-app
yarn
yarn watch # could be slow at the first time
# another terminal
yarn dev
# visit http://localhost:8080

You see, it’s mostly based on yarn, which is npm ecosystem. There’s not many JVM tools involved.

The macro create-tiny-app->

The package tiny-app provides a macro which bundles the dirty work into a single package.

Here’s how you called it:

(def app
  (create-tiny-app->
    {:model store
     :updater updater
     :view comp-container
     :mount-target (.querySelector js/document ".app")
     :ssr? false
     :show-ops? true}))

(def reload! (:reload! app))

(set! (.-onload js/window) (:start-app! app))

create-tiny-app-> is the Macro that creates the app and returns {:start-app! f1, :reload! f2}. The function reload! will be called by shadow-cljs, which is our ClojureScript compiler.

It will compile code from src/ into target/main.js for development.

Other works is to create index.html and load target/main.js on a browser. I use http-server, a npm package, to do the job.

MVC parts

You already saw :model :view :updater in the options. Yes, Respo is built with MVC pattern in mind. , view is the component we defined with Respo.

Model is immutable data. To define a store, make sure it’s a Map that contains :states {}, which initializes states:

(def store {:states {}
            :counter 0})

updater is a pure function for updating the store. op is the operation name represented in a keyword, op-data is an immutable value:

(defn updater [store op op-data]
  (update store :counter inc))

To learn about components, please read Respo Beginner Guide. Here a simple component:

(defcomp comp-demo []
  (div {:style {:color :red}}))

Troubleshooting

If you look into the code, you may find it requires many code. It’s necessary since we used Macro here. Be careful.

(ns app.main
  (:require-macros [tiny-app.core :refer [create-tiny-app->]]
                   [respo.macros :refer [defcomp <> div span button]])
  (:require [respo.core]
            [respo.cursor]))

And if you run into problems of shadow-cljs, please report to https://github.com/thheller/shadow-cljs/issues/ .
For Respo it’s https://github.com/Respo/respo/issues .