EDN and JSON
Prerequisites: Files and I/O
EDN — Clojure's data format
EDN (Extensible Data Notation) is Clojure's literal syntax used as a
data format: maps, vectors, sets, keywords, strings, numbers — exactly
what you write in code. Clojure projects use it for configuration
(deps.edn) and data exchange.
(require '[clojure.edn :as edn])
(def config-text "{:port 8080 :hosts [\"a.local\" \"b.local\"] :debug? true :started #inst \"2026-09-29T08:00:00.000-00:00\"}")
(def config (edn/read-string config-text))
(println (:port config) (count (:hosts config)) (:debug? config))
(println (type (:started config)))
(def data {:user/id 7 :tags #{:admin} :scores [1 2 3]})
(def text (pr-str data))
(println text)
(println (= data (edn/read-string text)))
8080 2 true
java.util.Date
{:user/id 7, :tags #{:admin}, :scores [1 2 3]}
true
pr-strwrites data as EDN;clojure.edn/read-stringreads it back.- Tagged literals like
#inst(a date) and#uuidextend the format. - Use
clojure.edn/read-string, notclojure.core/read-string, for data from outside: the core reader can evaluate code.
Pretty printing
(require '[clojure.pprint :refer [pprint print-table]])
(pprint {:service "api"
:replicas 3
:env {:DATABASE_URL "postgres://db/app" :LOG_LEVEL "info" :FEATURE_FLAGS "a,b,c"}
:ports [8080 9090]})
(print-table [{:name "Ada" :age 36} {:name "Linus" :age 28}])
{:service "api",
:replicas 3,
:env
{:DATABASE_URL "postgres://db/app",
:LOG_LEVEL "info",
:FEATURE_FLAGS "a,b,c"},
:ports [8080 9090]}
| :name | :age |
|-------+------|
| Ada | 36 |
| Linus | 28 |
JSON with clojure.data.json
JSON needs a library. org.clojure/data.json is the official one (and
cheshire and jsonista are popular faster alternatives). With the CLI,
add it to deps.edn: {:deps {org.clojure/data.json {:mvn/version "2.5.2"}}}.
(require '[clojure.data.json :as json])
(def text "{\"name\":\"tools-api\",\"version\":\"2.1.0\",\"maintainers\":[{\"name\":\"Ada\",\"active\":true}],\"limits\":{\"rps\":50}}")
(def parsed (json/read-str text :key-fn keyword))
(println (:name parsed))
(println (map :name (:maintainers parsed)))
(println (get-in parsed [:limits :rps]))
(println (json/write-str {:id 7 :tags ["clojure" "json"] :owner {:name "Ada"} :note nil}))
(json/pprint {:id 7 :tags ["a"]})
tools-api
(Ada)
50
{"id":7,"tags":["clojure","json"],"owner":{"name":"Ada"},"note":null}
{"id":7, "tags":["a"]}
:key-fn keywordturns JSON object keys into keywords, so the result looks like ordinary Clojure data.write-strconverts keywords to strings,niltonull.
Inspect JSON with the JSON Formatter and JSON Validator.