6  Demo

This page contains example Babashka code — each block is evaluated during rendering, and the results appear below.

For examples of every supported ^:kind/... annotation, see Kindly kinds — that page is also live.

6.1 Basics

(+ 1 2 3)
6
(str "Hello from " "Babashka!")
"Hello from Babashka!"
(defn square [x] (* x x))
(map square [1 2 3 4 5])
(1 4 9 16 25)

6.2 Stdout

Printed output appears alongside the return value:

(do (println "computing...") (* 6 7))
computing...
42

A hide-stdout=true fence attribute drops the captured stdout while keeping the value:

(do (println "debug — won't appear") (* 6 7))
42

6.3 Open data + Vega-Lite

Babashka ships an HTTP client. Fetch some data and chart it without ever leaving the notebook.

(require '[babashka.http-client :as http]
         '[cheshire.core :as json])
nil
(def quakes
  (-> (http/get "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.geojson")
      :body
      (json/parse-string true)
      :features
      (->> (map (fn [f]
                  {:place (-> f :properties :place)
                   :mag   (-> f :properties :mag)
                   :time  (-> f :properties :time)})))))
(count quakes)
29
^:kind/vega-lite
{:data {:values quakes}
 :mark {:type "bar" :tooltip true}
 :title "USGS earthquakes M≥2.5 (last 24h) — magnitude distribution"
 :encoding {:x {:field :mag :bin true :title "Magnitude"}
            :y {:aggregate :count :title "Count"}}}

The whole pipeline — HTTP, JSON, transform, chart spec, render — happens inside quarto render.

6.4 Hiccup

Annotate a vector with ^:kind/hiccup to render it as HTML:

^:kind/hiccup
[:svg {:width "300" :height "200" :xmlns "http://www.w3.org/2000/svg"}
  [:rect {:width "300" :height "200" :fill "#f0f0f0" :rx "10"}]
  [:circle {:cx "80"  :cy "100" :r "50" :fill "steelblue"}]
  [:circle {:cx "160" :cy "100" :r "40" :fill "coral"}]
  [:circle {:cx "230" :cy "100" :r "30" :fill "mediumseagreen"}]
  [:text {:x "150" :y "180" :text-anchor "middle" :font-size "14" :fill "#333"}
    "Generated by Babashka"]]
Generated by Babashka

The long form ^{:kindly/kind :kind/hiccup} works too:

^{:kindly/kind :kind/hiccup}
[:div {:style "padding:12px; background:#f0f0f0; border-radius:8px;"}
  [:b "Hello"] " from " [:em "Kindly"] "!"]
Hello from Kindly!

6.5 HTML

Use ^:kind/html to render a computed string as raw HTML. Since strings can’t hold metadata, wrap the expression in a vector:

^:kind/html
[(str "<div style='padding:8px; border:2px solid #4a90d9; border-radius:8px;'>"
      "<b>Computed HTML</b> via <code>kind/html</code>"
      "</div>")]
Computed HTML via kind/html

6.6 Plotly chart

Use ^:kind/plotly with a map containing :data and :layout keys:

(let [xs (vec (map #(* 0.5 %) (range 20)))
      ys (vec (map #(+ (* % %) (* -0.5 %)) xs))]
  ^:kind/plotly
  {:data [{:x xs :y ys
           :type "scatter" :mode "lines+markers"
           :name "y = x² - 0.5x"}]
   :layout {:title "Quadratic from Babashka"
            :xaxis {:title "x"}
            :yaxis {:title "y"}}})

width and height fence attributes resize the wrapper:

^:kind/plotly
{:data [{:x [1 2 3 4 5] :y [4 1 5 3 2] :type "bar"}]
 :layout {:title "Sized 400×250 via fence attrs"}}

See Per-block options for the full set and precedence rules.

6.7 HTML table

:kind/table renders tabular data on the Babashka side:

^:kind/table
[{:lang "Clojure"  :year 2007 :host "JVM"}
 {:lang "Babashka" :year 2020 :host "GraalVM/SCI"}
 {:lang "Jank"     :year 2019 :host "C++/LLVM"}
 {:lang "Cherry"   :year 2022 :host "JS/SCI"}]
:lang:year:host
Clojure2007JVM
Babashka2020GraalVM/SCI
Jank2019C++/LLVM
Cherry2022JS/SCI

6.8 Markdown table (computed)

Use ^:kind/md to render a string as markdown — handy when the table content itself is computed:

^:kind/md
[(let [headers ["x" "x²" "x³"]
       rows (map (fn [x] [(str x) (str (* x x)) (str (* x x x))]) (range 1 8))
       header-line (str "| " (clojure.string/join " | " headers) " |")
       sep-line (str "| " (clojure.string/join " | " (map (fn [_] "---") headers)) " |")
       row-lines (map (fn [row] (str "| " (clojure.string/join " | " row) " |")) rows)]
   (clojure.string/join "\n" (concat [header-line sep-line] row-lines)))]
x
1 1 1
2 4 8
3 9 27
4 16 64
5 25 125
6 36 216
7 49 343

6.9 LaTeX math

Since kind/md output is processed as markdown, LaTeX math works via $$...$$ syntax. Quarto renders it with MathJax:

^:kind/md
[(str "$$\\sum_{k=1}^{n} k = \\frac{n(n+1)}{2}$$")]

\[\sum_{k=1}^{n} k = \frac{n(n+1)}{2}\]

You can also build formulas from computed values:

^:kind/md
[(let [n 10
       result (/ (* n (+ n 1)) 2)]
   (str "For $n = " n "$:\n\n"
        "$$\\sum_{k=1}^{" n "} k = \\frac{" n " \\cdot " (+ n 1) "}{2} = " result "$$"))]

For \(n = 10\):

\[\sum_{k=1}^{10} k = \frac{10 \cdot 11}{2} = 55\]

Or use ^:kind/tex for a standalone formula:

^:kind/tex
["\\sum_{k=1}^{n} k^2 = \\frac{n(n+1)(2n+1)}{6}"]

\[\sum_{k=1}^{n} k^2 = \frac{n(n+1)(2n+1)}{6}\]

6.10 Annotating in library functions

Metadata doesn’t have to be in the code block — functions can attach it to their return values with with-meta. Define a bar-chart function that produces a Plotly chart and tags it as :kind/plotly:

^:kind/hidden
[(defn bar-chart [labels values]
   (with-meta
     {:data [{:x labels :y values :type "bar"}]
      :layout {:title "Bar Chart"}}
     {:kindly/kind :kind/plotly}))]

Now just call the function — no annotation needed at the call site:

(bar-chart ["apples" "bananas" "cherries"] [12 19 7])