The Clojure Reader and EDN

How the Clojure reader turns text into forms, where EDN fits as a data subset, and why `clojure.edn/read-string` is the safer default for config and interchange.

The Clojure reader is the broader mechanism that turns source text into Clojure forms. EDN lives inside that world as a data-oriented subset for configuration and interchange. A lot of beginner confusion comes from collapsing those two ideas into one.

EDN (Extensible Data Notation): A Clojure-friendly data notation that looks like ordinary Clojure literals but intentionally limits itself to data-oriented forms.

That distinction matters in practice:

  • the reader can parse code forms and reader syntax
  • EDN is meant for data, not arbitrary executable code
  • clojure.edn/read-string is usually the right tool for external data
  • clojure.core/read-string is not the safe default for config files or user input

The Reader Turns Text into Forms

The Clojure reader is the first layer in the language pipeline. It scans characters and produces in-memory forms such as:

  • lists
  • vectors
  • maps
  • sets
  • symbols
  • keywords
  • strings
  • numbers

For example:

1(+ 1 2 3)

The reader does not execute this expression. It first turns it into a list whose first element is the symbol + and whose remaining elements are numbers. Evaluation happens later.

That “code as data” property is what makes Lisp-style macros possible. But it also means you need to keep the reader and the evaluator conceptually separate.

Where EDN Fits

EDN feels natural in Clojure because its syntax is close to ordinary literals. But it deliberately narrows the surface to data-oriented forms rather than the full range of reader behavior.

Typical EDN values include:

 1;; A list
 2(1 2 3 4)
 3
 4;; A vector
 5[1 2 3 4]
 6
 7;; A map
 8{:name "Alice" :age 30}
 9
10;; A set
11#{1 2 3 4}
12
13;; Nested data
14{:user {:name "Bob" :age 25}
15 :roles [:admin :user]}

EDN is stronger than JSON when the domain benefits from:

  • keywords
  • sets
  • tagged literals
  • richer nested data without string-only keys

It is weaker when the surrounding ecosystem expects JSON everywhere and cross-language tooling convenience matters more than expressiveness.

Why EDN Is Useful

EDN remains popular in Clojure systems because it balances readability and structure well.

Its main advantages are:

  1. Richer data types than JSON, especially keywords, sets, and tagged literals.
  2. Human readability for configuration and local data files.
  3. Extensibility through tagged literals and custom readers.
  4. Alignment with Clojure values, so the data feels natural inside application code.

The real benefit is not theoretical elegance. It is that configuration and interchange data can stay close to the way Clojure programs already think about values.

Use clojure.edn/read-string for Data

The practical rule modern pages should teach is simple:

  • use clojure.edn/read-string for EDN data
  • do not casually use clojure.core/read-string for external input
1(require '[clojure.edn :as edn])
2
3(def config
4  (edn/read-string
5   "{:database {:host \"localhost\" :port 5432}
6     :features #{:audit :metrics}}"))
7
8(def serialized (pr-str config))

This boundary matters because EDN is intended for data interchange, while the full reader participates in a broader language model.

Tagged Literals and Custom Readers

One of EDN’s most useful features is tagged literals. They let you express specialized data without abandoning a readable text format.

 1(defn point-reader [[x y]]
 2  {:x x :y y})
 3
 4(def custom-readers {'point point-reader})
 5
 6(def point
 7  (clojure.edn/read-string
 8   {:readers custom-readers}
 9   "#point [10 20]"))
10;; => {:x 10 :y 20}

This is powerful, but it is best used with restraint. Tagged literals work well when the tag represents a stable domain concept. They work badly when they become an ad hoc object-construction escape hatch.

Visualizing Reader and EDN Syntax

The visual below focuses on anatomy rather than process. It labels the pieces readers often confuse: list delimiters, symbols, keywords, vectors, maps, sets, and tagged literals.

Annotated EDN and reader syntax examples showing a list form, an EDN map with keywords and a set, and a tagged literal.

What to notice:

  • (+ 1 2) is a list form, not an already executed computation
  • :name and :roles are keywords, which is one reason EDN feels natural in Clojure config
  • #{...} marks a set
  • #uuid is a tagged literal, which is part of EDN’s extensibility story

Once those shapes become visually familiar, the reader/EDN distinction gets much easier to reason about.

When EDN Fits Better Than JSON

EDN is a strong fit when the producer and consumer are already comfortable with Clojure-style data and the extra expressiveness is useful.

It is often the better choice for:

  • application configuration
  • local development settings
  • job definitions or workflow inputs
  • data fixtures for tests
  • internal interchange between Clojure services or tools

JSON is often the better choice when:

  • non-Clojure systems are the main consumers
  • the broader ecosystem expects JSON tooling everywhere
  • the data model does not need sets, keywords, or tagged literals

Practical Configuration Example

EDN is especially common in configuration because it stays readable while still supporting richer value shapes than JSON.

1;; config.edn
2{:database {:host "localhost" :port 5432}
3 :logging {:level :info}
4 :features #{:audit :metrics}}

That is usually enough structure to keep configuration expressive without making it feel like executable code.

Common Confusions To Avoid

  • The reader is not the evaluator. It parses forms first; execution happens later.
  • EDN is not “all of Clojure written as data.” It is a deliberately narrower data notation.
  • clojure.core/read-string is not the right default for external input just because it happens to parse text.
  • Tagged literals are helpful when they model stable domain data, not when they become a loophole for arbitrary object construction.

Further Reading

For further reading on EDN, visit the EDN Format documentation.

Ready to Test Your Knowledge?

Loading quiz…
Revised on Thursday, April 23, 2026