This worked surprisingly well!
The New Wave
One upgrade I had made to the 1.x version of Outboard was moving it from its
original base on the (now defunct)
to the sparer, lighter
Krell does the minimum needed to prepare ClojureScript’s Google
and consequently incorporates NPM dependencies and local JS less jankily.
These improvements then make the Vouch.io workflow demonstrated in this talk by
David Nolen possible:
Storybook, and then consume and present them from your
ClojureScript app, which uses
maintain app state. This comes with a number of benefits, leaning on each
library for what it does best and discarding its weaknesses:
- The app is coordinated in ClojureScript, with its immutable data structures eliminating whole classes of bugs
- State is the responsibility of
re-frame, which has a simple and boilerplate-free functional interface
- Pure JS/JSX components reduce the temptation to spread state references up and down the stack
- Storybook uses React Native Web to present those JS components locally for design tweaks
Once these pieces are fit together, the development experience is blissful. The functional ClojureScript shell I had built for version 1 worked without changes, and new features I wanted to add required no refactoring. With JSX and Storybook, I was able to quickly and easily incorporate Tailwind for React Native to first replicate the original design, then significantly improve it. Design changes propagate to the app running in the simulator or on a phone instantly, with the ClojureScript REPL connected to test how it reacts to state changes. The frustrating tweak-compile-click-check-tweak cycle is gone.
Finding up-to-date (or any) documentation on setting this all up was a frustrating experience, but I’ve hopefully solved a lot of the pain with a new React Native template that does it all for you.
npx react-native init YourProjectName --template react-native-template-cljs-krell-storybook
The complete workflow of both designing your components with Storybook and running a ClojureScript REPL boils down to three processes:
This runs the Krell REPL via Clojure’s CLI (
clj -M -m krell.main -co build.edn
yarn run ios # or android
This compiles and runs the app on the simulator, as well as starts up the Metro bundler.
This starts the Storybook server and opens it in your browser, and will refresh as you make changes.
As in my original 2018 blog post, there continue to be tradeoffs with chaining together a number of different languages and platforms. Combining the benefits of functional, immutable development in ClojureScript with the ubiquity and gigantic ecosystem of React Native can make for an astoundingly productive flow, but that flow can be interrupted by mismatches between the various toolchains and build systems you have to connect to make it work. For me, though, as long as ClojureScript is an available platform to build apps like this on, I will continue to make that tradeoff.