React apps now run on the desktop with Electron. They also run on the desktop with react-native-desktop, or proton-native. In this simple post, I’ll share my (very small!) experience with proton-native:
First, you need Shadow-CLJS. Because of the npm integration, you can literally just:
npm install proton-native react react-dom create-react-class
And then add [reagent "0.8.1"]
to dependencies on shadow-cljs.edn
file. Then, configure a :node-script
target and start to build things. This means that your shadow-cljs.edn
file will be:
{:source-paths ["src" "test"] :dependencies [[reagent "0.8.1"]] :builds {:desktop {:target :node-script :main demo.app/init :output-to "target/index.js"}}}
Now, you have to create the src/demo/app.cljs
with the following contents:
(ns demo.app (:require [reagent.core :as r] ["react" :as React] ["proton-native" :refer [render Window App Button Box]])) (defonce state (r/atom 0)) (defn- win [] [:> Box [:> Button {:stretchy false :onClick #(prn :Bye)} "Click Lol!!"] [:> Button {:stretchy false :onClick #(swap! state inc)} @state]]) (defonce primary-view (r/atom win)) (defn example [] [:> App [:> Window {:title "Example" :size {:w 300 :h 300} :menuBar false} (r/as-element [@primary-view])]]) (defn init [ & args] (render (r/as-element [example]))) (defn ^:dev/after-load reload [] (reset! primary-view win))
There is something that we need to be aware: if you look at example
implementation, you’ll see that it derefs the primary-view
reagent atom. By doing it, we get auto-reload for free, and its even more impressive considering that it is not supported by proton-native!.