Babashka `bb` and Not Babashka `nbb`
29 August, 2024
bb
Babashka is a native Clojure interpreter for scripting with fast startup. Its main goal is to leverage Clojure in places where you would be using bash otherwise.
TLDR;
bb -e '(+ 1 20)'
bb -e '(-> (org.httpkit.client/get "https://datafy.id") deref :status)'
bb tasks
cat <<EOF > bb.edn
{:tasks {hello (println "hello there")}}
EOF
bb hello # run the task named hello
nbb
Not Babashka. Node.js Babashka!? nbb
is bb
atop JS runtime, e.g.
bun or nodejs.
Getting Started
# Using bun, this will automatically download nbb if necessary
# and compute bcrypt hash of given password
bunx --bun nbb -e '(js/Bun.password.hash "pass" #js {:algorithm "bcrypt"})'
We can make it more organized by creating config file nbb.edn
and create a
cljs file.
mkdir x && cd x
touch nbb.edn
touch hello.cljs
Config file nbb.edn
could be as simple as this:
{:paths ["."]}
And the hello.cljs
content, for example shown here, we will use bun
hash
api.
(ns hello)
(defn greeting [& {:keys [to]}]
(println (str "Hello " to)))
(defn -main [& [password]]
;; note that if we return promise, it will be automatically waited
;; and then result is printed
(js/Bun.password.hash password #js {:algorithm "bcrypt"}))
(defn bcrypt [& {:keys [password]
:or {password "pass"}}]
(-> (js/Bun.password.hash password #js {:algorithm "bcrypt"})
(.then (fn [x]
{:password password
:hash x}))))
With these two files, now we could execute the script with nbb like this:
bunx --bun nbb -x hello/greeting --to "Ridho"
bunx --bun nbb -x hello/bcrypt --password your_strong_password
bunx --bun nbb -x hello/bcrypt :password "your_strong_password" # same like above
bunx --bun nbb -m hello your_strong_password
nbb Api
See latest api doc here.
Builtin NS: clojure.core
, clojure.set
, clojure.edn
, clojure.string
,
clojure.walk
, clojure.data
, clojure.test
and clojure.pprint
.
nbb.core
: *file*
, load-file
, load-string
, slurp
, time
.
nbb.repl
: repl
, socket-repl
.
nbb.error
: print-error-report
.
babashka.cli
: auto-coerce
, coerce
, dispatch
, format-opts
,
format-table
, merge-opts
, number-char?
, opts->table
, pad
, pad-cells
,
parse-args
, parse-cmds
, parse-keyword
, parse-keyword
, rows
,
spec->opts
.
promesa.core
: *loop-run-fn*
, ->
, ->>
, TimeoutException
, all
,
any
, as->
, bind
, cancel!
, cancelled?
, catch
, catch'
, chain
,
chain'
, create
, deferred
, deferred?
, delay
, do
, do!
, done?
,
err
, error
, finally
, future
, handle
, let
, loop
, map
, mapcat
,
pending?
, plet
, promise
, promise?
, promisify
, race
, recur
,
reject!
, rejected
, rejected?
, resolve!
, resolved
, resolved?
, run!
,
then
, then'
, thenable?
, timeout
, with-redefs
, wrap
.
reagent.core
: atom
, as-element
, with-let
, cursor
, create-class
,
create-compiler
.
reagent.ratom
: with-let-values
, reactive?
.
reagent.dom.server
: render-to-string
, render-to-static-markup
.
applied-science.js-interop
: get
, get-in
, contains?
, select-keys
,
lookup
, assoc!
, assoc-in!
, update!
, extend!
, push!
, unshift!
,
call
, apply
, call-in
, apply-in
, obj
, let
, fn
, defn
, lit
.
clojure.tools.cli
: format-lines
, summarize
, get-default-options
,
parse-opts
, make-summary-part
.
cognitect.transit
: write
, writer
, write-handler
, write-meta
,
read
, read
, read-handler
, tagged-value
.
cljs-bean.core
: bean
, bean?
, object
, ->js
, ->clj
.