I wanted to enter the js13k game jam.
I wanted to use "ClojureScript".
I wanted to use "Reagent".
Is there some way I could build a <13kb artifact with these constraints? Seems impossible.
Solution: I forked https://bitbucket.org/sonwh98/mr-clean/ and spent two sleepless nights slop-coding it to build with squint-cljs , and somehow it worked!
Demo: https://chr15m.github.io/eucalypt/ <- 10kb index.html + js + CSS artifact 😀
Demo source: https://github.com/chr15m/eucalypt/blob/main/demo/main.cljs
Library: https://github.com/chr15m/eucalypt
Tradeoffs: if you squint hard enough it looks like Reagent, but it certainly isn't. It's very much a scrappy fiddle. Lots and lots of bugs, and I used an LLM to slop-code it fast. That said, I plan to iterate on this, put together some tests etc. so maybe it will be useable in future. Of course you're welcome to take it for a spin and PRs are most welcome!
Ok, this doesn't work for the game jam, for well, reasons, but it's mental and potentially fun for other purposes:
indentation brought to you by whatever HTML+ mode in emacs feels like doing with whatever this is. Ha! 🤭
I got the Reagent homepage demos working with Eucalypt, including the Todo MVC demo. https://chr15m.github.io/eucalypt/ 👇 Also lots more tests.
RUN v1.6.0 /home/chrism/dev/eucalypt ✓ src/test/src/standard_attributes.test.mjs (3) ✓ src/test/src/multiple_instances.test.mjs (3) ✓ src/test/src/fragment_clickable.test.mjs (1) ✓ src/test/src/component_switching_bug.test.mjs (1) ✓ src/test/src/attribute_handling.test.mjs (6) ✓ src/test/src/list_rerender.test.mjs (2) ✓ src/test/src/todomvc.test.mjs (10) 1473ms ✓ src/test/src/multiple_select.test.mjs (1) ✓ src/test/src/nested_fors.test.mjs (3) ✓ src/test/src/range_slider.test.mjs (2) ✓ src/test/src/radio_buttons.test.mjs (1) ✓ src/test/src/enter_to_submit.test.mjs (1) ✓ src/test/src/various_events.test.mjs (3) ✓ src/test/src/timer.test.mjs (1) 675ms ✓ src/test/src/boolean_attributes.test.mjs (1) ✓ src/test/src/basic_components.test.mjs (4) ✓ src/test/src/select.test.mjs (1) ✓ src/test/src/checkbox.test.mjs (1) ✓ src/test/src/list_demo.test.mjs (1) ✓ src/test/src/numeric_input.test.mjs (1) ✓ src/test/src/select_attribute.test.mjs (1) ✓ src/test/src/fragment_switching.test.mjs (1) ✓ src/test/src/style_attribute.test.mjs (1) ✓ src/test/src/prop_change_rerender.test.mjs (1) ✓ src/test/src/text_input.test.mjs (1) ✓ src/test/src/ref.test.mjs (1) ✓ src/test/src/various_renderings.test.mjs (6) ✓ src/test/src/textarea.test.mjs (1) ✓ src/test/src/svg.test.mjs (1) ✓ src/test/src/local_state_rerender.test.mjs (1) ✓ src/test/src/click_swap.test.mjs (1) ✓ src/test/src/simple_component.test.mjs (1) ✓ src/test/src/empty_fragment.test.mjs (1) ✓ src/test/src/stateful_component.test.mjs (1) Test Files 34 passed (34) Tests 66 passed (66) Start at 17:22:35 Duration 4.06s (transform 268ms, setup 3ms, collect 3.05s, tests 3.30s, environment 9.14s, prepare 4.60s)
688 lines of vibe-coded squint-cljs. 😹
w000t!
this is insane :)
I'll post something to #announcements if I can get it to the point where I trust the LLM generated code enough not to be completely embarrassed. I think I just need a lot more tests to get there.
ok
I love how were at this funny moment in history where caring people are trying not to be embarrassed by their use of llms ("Why didn't I use chatGPT to do the calculations? Because I wanted them to be correct."), while other people are like, "Look at this amazing thing I made!" 🙂
I didn't get a game done in time, but I https://github.com/chr15m/eucalypt/tree/main/test/src. Still heaps of bugs though and I don't know if this Reagent-like-in-Squint angle is worth pursuing. 🤔 I may pursue it anyway just because it feels like something I will need in the future.
I got a lot of tests workingThat is rad.
It's a weird time for sure. I makes sense that can be true at the same time if you consider LLMs to be a new and powerful tool with many footguns.
This is amazing :)
btw preact could maybe also work if you want normal react API?
3kb
this is what the cljdoc front-end uses
but I admire your courage to implement reagent from scratch in squint :)
I tried out Preact and Hyperscript - I will look at them again to compare. Mostly it's about having a Reagent-like API.
Wild. Another potentially useful data point (lying somewhere in a similar space to reagent / mr clean) would be replicant: https://github.com/cjohansen/replicant It's not 'reagent compatible' per-se, but it has a related (though simplified, and more data-oriented) model, and is small (no react dep)
It would make a lot of sense to use replicant as a rendering engine. I wonder how hard it would be to get it to compile with squint? 🤔
This is a cool thread - I'm a big fan of delivering small artifacts
It occurred to me that another fun possibility here would be to use p5.js, compile the game code with squint, and feed both through the closure compiler to try and tree shake / minimize it down below 13k. The first thing I tried didn't work (the p5.js file has some undefined stuff according to the closure compiler):
COMPILER_FILE="closure-compiler-v20250706.jar"
COMPILER_URL=""
if [ ! -f "$COMPILER_FILE" ]; then
echo "Closure compiler not found. Downloading..."
cCOMPILER_URL -o "$COMPILER_FILE" "$COMPILER_URL" || wget -O "$COMPILER_FILE" "$COMPILER_URL"
else
echo "Have closure compiler."
fi
P5_FILE="p5.js"
P5_URL=""
if [ ! -f "$P5_FILE" ]; then
echo "p5.js not found. Downloading..."
cP5_URL -o "$P5_FILE" "$P5_URL" || wget -O "$P5_FILE" "$P5_URL"
else
echo "Have p5.js."
fi
java -jar $COMPILER_FILE \
--js p5.js \
--js game.js \
--compilation_level ADVANCED_OPTIMIZATIONS \
--js_output_file game.min.js
But maybe it could be a starting point if someone wants to try.Dude you are in another level! Crazy cool