Skip to content

loganrios/ksapp

Repository files navigation

Keionsoft App Template

This is the ever-evolving app template for Keionsoft Consulting’s app development efforts. Heavily in alpha, so expect constant updates and breaking changes–however, this template merges a couple important things that would be a real pain to reinstall.

What is this? It’s a React Native starter app with ClojureScript bootstrapped into it via Krell and the ability to create components in Storybook. It’s essentially the Vouch stack, as discussed by David Nolen in his talk “ClojureScript in the Age of TypeScript”: https://www.youtube.com/watch?v=3HxVMGaiZbc.

Literally why would anybody do something so complicated?

  • React Native lets me write code for iOS, Android, and a scuffed web deployment at the same time
  • ClojureScript is more powerful, more terse, and less syntactically stupid than JS
  • Krell is an easy dependency, and interactive REPL-based programming is literally the best thing ever
  • Storybook helps with keeping business logic out of “Views”, and lets us test our UIs with dummy data before they ever reach the target device

Note: get ready for long compile and bundle times.

Prerequisites

You will need:

  • A computer running macOS
  • NodeJS (only tested with v16)
  • yarn package manager
  • Clojure (latest version)
  • ClojureScript (note: added to deps.edn to avoid the global install)
  • XCode and an iOS Simulator installation
  • Doom Emacs (with javascript and clojure modules enabled)

This project file could probably be adapted to use some other tooling, but this is my in-house stack, so at the moment it’s all I plan on supporting.

Installation

Yes, this is a nightmare. Maybe someday I will write a script that does all of this automatically, but honestly Node projects are such a black box that you’ll probably have to nuke your generated directories and run these same commands in some arbitrary fashion at least 2-4 times. YMMV.

First, clone this repository, via SSH (not HTTPS, you cowards), then run the following commands to completion:

# Fetch all the node dependencies
yarn install

# Fetch all the CLJS dependencies for Krell
clj -M -m cljs.main -co "{:deps-cmd \"yarn\"}" --install-deps

# Go into the ios/ directory and install the pods
cd ios; pod install; cd ..

# Then, build the project.
clj -M -m krell.main -v -co build.edn -c

In that same directory, open up three terminals (or two terminals + Emacs w/ CIDER). In the first terminal, run the following command:

npx react-native start

In the second terminal, run the following command:

npx react-native run-ios

(If you get the warning “Already Booted”, just disregard. I don’t know what it is or does.)

Then, in your last terminal, run the following command:

clj -M -m krell.main -co build.edn -c -r

This should open up a CLJS REPL that is connected to your running iPhone simulator instance. To confirm it’s working, wait until you see the prompt cljs.user=> show up, then type the following in (note the pre-empting prompt which you do not type):

cljs.user=> (js/alert "hello whirled!")

If all goes well, you should see an alert pop up on the iPhone simulator matching your inputted text. Feel free to kill everything at this point.

Storybook Configuration

So, Storybook doesn’t work out of the box (shocker in the JS world). Get ready for more package management screwery.

Note: you want to do this after you confirm the Krell portion of the build–for some reason, it likes to overwrite the version of React. You want the latest for Storybook, otherwise you’ll get a blank screen and zero explanation.

# Upgrade to the latest React (it works with Krell anyway ig)
yarn add react@latest

# Then, add a whole bunch of dependencies to make
# Storybook understand React-Native stuff in web mode.
yarn add react-dom react-native-web babel-plugin-react-native-web @storybook/addon-react-native-web --dev

Verify that your .storybook/main.js file has the following addon:

module.exports = {
  addons: [/*existing addons,*/ '@storybook/addon-react-native-web'],
};

Then, run yarn storybook and witness the glory. If it doesn’t work, rm -rf node_modules; yarn install and try yarn storybook again.

Usage

To be totally honest, I’m not 100% sure this thing even works, but this is where we’re at. I haven’t tested the js/require functionality at all, and I have no clue how nicely the JS components and CLJS are going to play in the long run. But hey, we got this far, right?

As a daily driver, you’ll basically follow these three steps:

  1. Open up a dedicated terminal and run npx react-native start
  2. Create another terminal and run npx react-native run-ios
  3. In Emacs, navigate to some Clojure-like file (.edn, .cljs, etc.)
  4. From that Clojure file, run M-x cider-jack-in-cljs (or ~SPC m “~ if you’re a cool Doomacs user), choose option “krell”, and wait until the cljs.user=> prompt appears (not just user=>!), then do interactive coding to your heart’s content.

Roadmap

Things that I will probably eventually do (someday):

  • [ ] Bash or Babashka script to automate all this setup
  • [ ] react-native-web support, a la Expo
  • [ ] Possibly get Expo’s insanely nice tooling in here (QR codes on the iPhone, whaaaat?)
  • [ ] Integrate other useful CLJS libraries (re-frame, polylith?)
  • [ ] Integrate Fastlane for ease of deployment (we have a Ruby dependency already ig)
  • [ ] Integrate good default RN libraries that help the app development use case
  • [ ] Get boilerplate for a GraphQL or REST backend loaded
  • [ ] Steal Fulcro’s ideas

Contributing

Any and all Pull Requests and Issues are welcome–I want this template to be as robust and useful as possible for both my own company and fellow #cljsrn devotees.

Acknowledgements

Most of this template is just a compilation from various sources, all of whom deserve more credit than I do for their genius. Credit where credit is due–I couldn’t have made my dream stack work without help from all these folks:

  • Vouch.io (both Krell and the example projects)
  • Storybook team (for SB itself and the clutch React-Native-Web addon)
  • David Nolen (@swannodette) for tons of useful answers in the Clojurians \#cljsrn channel
  • PEZ (@pez) for also having useful CLJS templates that are easier to use than mine
  • Henrik Lissner (@hlissner) for making Doom Emacs, the best text editor of all time

Let’s keep the Simple Made Easy dream alive, everyone!