Fork me on GitHub

is there a good way to eval some cljs from node with lumo?


I don't see it documented in the repo


I'd like to run a bootstrap start script that calls a commonJS exported method and passes it to a cljs function that is transpiled as it's called rather than built up-front



import * as lumo from 'lumo-cljs'
const cljs-handler = require('src/cljs-handler/core.cljs')

exports.handler = (event, context, callback) => lumo.eval(cljs-handler(event, context, callback));


@johnjelinek this is not possible, what you could do is just spawn lumo from node

var lumoProcess = spawn(process.cwd() + '/node_modules/lumo-cljs/bin/lumo',
                        			['-e', 'insert code here', '-m', 'or run a script with main', 'or without a main like (load-file ...)']);
// get the return values
lumoProcess.stdout.on('data', (data) => {

lumoProcess.stderr.on('data', (data) => {


would this be a good feature?


For me, I'd like to cut down transpile time and I haven't been able to figure out how to call transpiled output with :optimizations :none


since I'm deploying code on the backend -- I don't have any need to bundle and minify and what-not


have yout tried adding :^export to your function you want to call from js-land?


ya -- but even then, I have to do this:

const cljs-handler = ('./out/main.js')

exports.handler = (event, context, callback) => cljs-handler.cljs-handler.core.handler(event, context, callback);


because the stuff from Google Closure doesn't export to CommonJS format


I thought maybe I could do :optimizations :none and then in my bootstrap file:

const cljs-handler = ('./out/main')
but then it complains about not finding goog in the global namespace


so -- I pushed this example last night: It would be nice to not have to run npm run build before being able to npm start


@johnjelinek my two cents on your two questions ;):


1. requiring lumo from a standard js project sort of mitigates the value prop of lumo, in that case you may prefer to simply import the bootstrapped cljs library ala


>Status > >Very early. Do not use for anything critical. Contributions welcome! ☝️ doesn't make me feel too warm n' fuzzy


also, I don't see how it mitigates the value prop of lumo -- is the alternative to take a dep on Java?


Hi John! so regarding the ‘status’ warning there, that code base is really just a small shim around the bootstrap clojurescript compiler aka cljs.js which is actually pretty stable 🙂 The bootstrapped compiler is still very young so you could say the whole project is a ‘not for production’ status though I’ve been running plenty of cljs code and I find the compiler output relatively robust


and for the second comment, what I mean to say is that the value proposition of lumo is really about pre-loading the bootstrapped cljs repl into the v8 snapshot for a fast ‘native like’ experience. Requiring lumo as a library doesn’t make use of much of what separates lumo from just simply using the cljs compiler. The alternative would be simply to use the compiler (which is just js anyway) from node.js, imo that makes more sense in than including, for example, the lumo repl implementation. Hope I’m understanding your use case properly 👍


oh, is there an official nodejs implementation of a cljs compiler? I thought that's what lumo was for


No there is not an official nodejs compiler, instead clojure can generate clojurescript code that includes the compiler in the resulting javascript. This is what they call ‘self-hosted’ or ‘bootstrapped’ and basically the clojurescript compiler is available to all javascript targets as a essentially a library


That code can be run with node.js. But it can also run on other js platforms like Rhino, JavascriptCore (MacOS), browsers


It’s all very inception


ya, but that requires a dependency on Java -- I don't want to take that dependency -- so I'm using lumo to fulfill that dependency instead


2. re usage of cljs in AWS lambda, my company has been including static binaries into our lambda releases with the help of (, we are simply popping the lumo linux binary in there instead of building lambda compatible js. So far this has been really awesome as we’re not bound to their older js runtimes


@bhurlow: do you have any examples of this? This is what I had in mind for one of my upcoming steps.


how do you bootstrap the static binary? I suppose you follow a convention of up?


I’m sure it’s possible without using up, but up takes care of this pretty nicely. Take a look here:


namely this:


"proxy": {
    "command": "./node-v8.4.0-linux-x64/bin/node app.js"


^ so for a lumo project, that’d look something like ./lumo-1.8-linux script.cljs


that’s how up is able to support non-official runtimes in lambda such as Go or Crystal


ok, so I'm looking at up a bit more -- it appears like it encourages you to develop services instead of microservices -- where you're serving static content and the whole backend in a single lambda deployment -- is that correct?


does up just kill the HTTP server after a 200 response is delivered?


also -- how does up handle services that aren't meant to be triggered by API Gateway?


Yea, up is a bit of an unconventional use for lambda. Traditionally the lambda idea was to have a small function that exits after the first request, but up instead opts to leave a server running inside the lambda vm for its lifecycle


its a bit counter-intuitive but it works pretty well


So up does NOT kill the HTTP server after a 200, it leaves it running until lambda kills that vm and/or starts another instance


that means that every so ofter there’s a slower request which is triggering a ‘cold boot’, but subsequent requests would hit the already running server


As far as non gateway services, up is designed for web services, there are some other tools for worker style lambda routines


@bhurlow can you expand on 2? I am interested. At the moment I am using serverless-cljs-plugin in order to compile down to JS with lumo


@richiardiandrea sure, so there’s sort of a popular emerging pattern with lambda which is to include your own linux binary, could be golang, jvm, whatever you want and shell exec that inside of the lambda boot. TJ has done a great job wrapping that with apex and up (two comparable projects)


This relates to lumo because to run cljs code in the lambda environment, all you have to do is include the lumo linux binary in the lambda zip file and configure lamba to execute that instead of their supplied js runtime. Takes a bit of shimming around but this allows you to run pretty much whatever you’d like to in the serverless VM, including CLJS


Because lumo is optimized for fast startup, its a pretty good experience


have heard of people using to run docker containers, which would be another path for running lumo


@bhurlow but fast startup will always be lower than compiled JS right? I know there might be other benefits about running Cljs script given the lumo repl, but lumo has macro and stuff that make it slower.


I bet if you did some benchmarks, the difference would be negligible


lumo caches macro dependencies using transit so the lambda should read these files outside the handlers or you are going to pay this cost all the time


it is optimizable of course, but something to be aware of, even if you have -K in place


@richiardiandrea true, good thing to note


yeah well the advantage would be to run node 9.2.0