HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
edn-format
edn
Data & Databases2012–2026
edn-format / edn

edn

Extensible Data Notation

87Distinct people
121Mentions
1Explicit recommenders
2.8KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Extensible Data Notation

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

I wonder, how rigidly has the JSON format been baked into the protocol. It feels like a shortsighted choice, just because it's prevalent in recent decades. It took years to…

onetom used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 12:03:30 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year121 dated mentions

Observed mentions: 2012-11-09 13:01:51 UTC to 2026-09-02 19:55:49 UTC.

051015202012-01-01 00:00:00 UTC to 2013-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20122013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 9 mentions; 1 submissions, 8 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 12 mentions; 0 submissions, 12 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 7 mentions; 0 submissions, 7 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 11 mentions; 1 submissions, 10 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 19 mentions; 2 submissions, 17 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 13 mentions; 1 submissions, 12 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 10 mentions; 1 submissions, 9 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 8 mentions; 1 submissions, 7 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 11 mentions; 0 submissions, 11 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 5 mentions; 1 submissions, 4 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20122012-01-01 00:00:00 UTC2013-01-01 00:00:00 UTC101
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC404
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC918
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC202
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC12012
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC707
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC11110
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC19217
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC13112
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC1019
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC817
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC11011
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC505
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC514
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC404

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
edn extensible data notation [eed-n] Rationale edn is an extensible data notation. A superset of edn is used by Clojure to represent programs, and it is used by Datomic and other applications as a data transfer format. This spec describes edn in isolation from those and other specific use cases, to help facilitate implementation of readers and writers in other languages, and for other uses. edn supports a rich set of built-in elements, and the definition of extension elements in terms of the others. Users of data formats without such facilities must rely on either convention or context to convey elements not included in the base set. This greatly complicates application logic, betraying the apparent simplicity of the format. edn is simple, yet powerful enough to meet the demands of applications without convention or complex context-sensitive logic. edn is a system for the conveyance of values. It is not a type system, and has no schemas. Nor is it a system for representing objects - there are no reference types, nor should a consumer have an expectation that two equivalent elements in some body of edn will yield distinct object identities when read, unless a reader implementation goes out of its way to make such a promise. Thus the resulting values should be considered immutable, and a reader implementation should yield values that ensure this, to the extent possible. edn is a set of definitions for acceptable elements. A use of edn might be a stream or file containing elements, but it could be as small as the conveyance of a single element in e.g. an HTTP query param. There is no enclosing element at the top level. Thus edn is suitable for streaming and interactive applications. The base set of elements in edn is meant to cover the basic set of data structures common to most programming languages. While edn specifies how those elements are formatted in text, it does not dictate the representation that results on the consumer side. A well behaved reader library should endeavor to map the elements to programming language types with similar semantics. Spec Currently this specification is casual, as we gather feedback from implementors. A more rigorous e.g. BNF will follow. General considerations edn elements, streams and files should be encoded using UTF-8. Elements are generally separated by whitespace. Whitespace, other than within strings, is not otherwise significant, nor need redundant whitespace be preserved during transmissions. Commas , are also considered whitespace, other than within strings. The delimiters { } ( ) [ ] need not be separated from adjacent elements by whitespace. # dispatch character Tokens beginning with # are reserved. The character following # determines the behavior. The dispatches #{ (sets), #_ (discard), #alphabetic-char (tag) are defined below. # is not a delimiter. Built-in elements nil nil represents nil, null or nothing. It should be read as an object with similar meaning on the target platform. booleans true and false should be mapped to booleans. If a platform has canonic values for true and false, it is a further semantic of booleans that all instances of true yield that (identical) value, and similarly for false. strings Strings are enclosed in "double quotes". May span multiple lines. Standard C/Java escape characters \t, \r, \n, \\ and \" are supported. characters Characters are preceded by a backslash: \c, \newline, \return, \space and \tab yield the corresponding characters. Unicode characters are represented with \uNNNN as in Java. Backslash cannot be followed by whitespace. symbols Symbols are used to represent identifiers, and should map to something other than strings, if possible. Symbols begin with a non-numeric character and can contain alphanumeric characters and . * + ! - _ ? $ % & = < >. If -, + or . are the first character, the second character (if any) must be non-numeric. Additionally, : # are allowed as constituent characters in symbols other than as the first character. / has special meaning in symbols. It can be used once only in the middle of a symbol to separate the prefix (often a namespace) from the name, e.g. my-namespace/foo. / by itself is a legal symbol, but otherwise neither the prefix nor the name part can be empty when the symbol contains /. If a symbol has a prefix and /, the following name component should follow the first-character restrictions for symbols as a whole. This is to avoid ambiguity in reading contexts where prefixes might be presumed as implicitly included namespaces and elided thereafter. keywords Keywords are identifiers that typically designate themselves. They are semantically akin to enumeration values. Keywords follow the rules of symbols, except they can (and must) begin with :, e.g. :fred or :my/fred. If the target platform does not have a keyword type distinct from a symbol type, the same type can be used without conflict, since the mandatory leading : of keywords is disallowed for symbols. Per the symbol rules above, :/ and :/anything are not legal keywords. A keyword cannot begin with :: If the target platform supports some notion of interning, it is a further semantic of keywords that all instances of the same keyword yield the identical object. integers Integers consist of the digits 0 - 9, optionally prefixed by - to indicate a negative number, or (redundantly) by +. No integer other than 0 may begin with 0. 64-bit (signed integer) precision is expected. An integer can have the suffix N to indicate that arbitrary precision is desired. -0 is a valid integer not distinct from 0. integer int int N digit 0-9 int digit 1-9 digits + digit + 1-9 digits - digit - 1-9 digits floating point numbers 64-bit (double) precision is expected. floating-point-number int M int frac int exp int frac exp digit 0-9 int digit 1-9 digits + digit + 1-9 digits - digit - 1-9 digits frac . digits exp ex digits digits digit digit digits ex e e+ e- E E+ E- In
Read the full README on GitHub

What Hacker News says

10 sources
Sure, but why move to an alternative that's almost as bad? YAML's problem is that whitespace is significant. TOML could be superior to it if it weren't for the fact that they forgot to forbid indentation. And now indented TOML is everywhere, including its wikipedia page. If we have to make a change, why not finally bite the bullet and go to the form that has existed for decades and is obviously superior to all of these formats? S-expressions. There's even been a standard for data notation brewing for some time: https://github.com/edn-format/edn Then we can actually forego http://xkcd.com/927 and do something useful with our significantly saved mental energy. edit I see that I'm not at all alone in wanting edn to replace all this crap. So some action points on how to actually make that happen, in order of preference: - write or improve rob
Read the rest
ust edn parsers for your ecosystem - write or improve robust x => edn converters for your ecosystems (x=yaml,json,toml,whateverpoisontheyuserightnow) - use edn in your projects - advocate the use of edn
In YAML: It's Time to Move On
From a practical standpoint, defining numbers in JSON to be "whatever double precision binary floating point does, or optionally something more precise" would have been good enough, and capture what we end up having anyway. Still, I prefer Crockford's choice: that JSON numbers are defined to be numbers. Infinity and the flavors of NaN are... not numbers. In an extensible data interchange format, like [edn][1], people could define conventions about more specific interpretations of numbers, e.g. #ieee754/b64 45.6653 ; this is a double We could build such a format on top of JSON (there are probably multiple), but I again agree with Crockford that this sort of thing does not belong in JSON. Makes for a bunch of headaches, though, for sure. One example is a data scientist I used to work with. He was working with lots of machine learning
Read the rest
libraries that liked to use NaN to mean "nothing to see here." A fellow developer ended up writing code that used some sort of convention to work around it, e.g. number := decimal | {"magic-uuid": "NaN"}. I can see why some people are of the opinion "this is stupid, just allow NaNs." I disagree. [1]: https://github.com/edn-format/edn
In Parsing JSON Is a Minefield (2016)
> S-expressions inherits all trouble with data types from json (dates, times, booleans, integer size, number vs numeric string). Hm, not sure that's true, S-expressions would only define the "shape" of how you're defining something, not the semantics of how you're defining something. EDN https://github.com/edn-format/edn for all purposes is S-expressions and have support for custom literals and more, to avoid "the trouble with data types from JSON"
In The Norway Problem
Seems you're missing my personal favorite, extensible data notation - EDN (https://github.com/edn-format/edn). Probably I'm a bit biased coming from Clojure as it's widely used there but haven't really found a format that comes close to EDN when it comes to succinctness and features. Some of the neat features: Custom literals / tagged elements that can have their support added for them on runtime/compile time (dates can be represented, parsed and turned into proper dates in your language). Also being able to namespace data inside of it makes things a bit easier to manage without having to result to nesting or other hacks. Very human friendly, plus machine friendly. Biggest drawback so far seems to be performance of parsing, although I'm not sure if that's actually about the format itself, or about the small adoption of the format and ther
Read the rest
efore not many parsers focusing on speed has been written.
In The Norway Problem
Welcome! You'll be glad for it (and cranky about it). This sensation is what many of us feel when we find the incidental complexities of things designed to be simple. Once you find enough you start to spot them yourself, and then you see them everywhere. The ugly part is... you see them everywhere. The beautiful part is you don't just get pattern recognition, you get a familiar solution mapping. I felt this way as a young programmer really getting my teeth in. I was also self-taught, so I didn't have familiarity with some things that would probably be considered basics/fundamentals. My advice regardless is: when you get this unsettling mind-expanding feeling go research prior art. Go find out how other people solve problems like it. Even if you come up wanting more/better, at least you have a lay of the land. And learn the terminology use
Read the rest
d describing the problem space to expand your hunt. You'll be amazed what you turn up! Edit: since this is on the topic of JSON (de)serialization, while I’d love to tout the very good pattern I see in my usual stack (TypeScript) where I’m working on an offering in the space, I’d actually recommend looking at prior art in a very different stack with very different goals: - Transit[1] which standardizes type metadata within JSON (but leaves type resolution up to producers/consumers). - EDN[2], which is the philosophical basis for Transit, written in Clojure syntax. It’s demonstrably worse for performance but syntactically a nicer format/DX if you have tooling to deal with it, and it’s nearly tooling-free if you use the stack. A lot of efforts to standardize rich data type representation in JSON unfortunately do it very haphazardly, so I wanted to include examples that come from the “pattern recognition/solution mapping” side as an example. Both have downsides, but they’re exceptionally well designed for what they are and deserve to be part of this discussion. [1]: https://github.com/cognitect/transit-format [2]: https://github.com/edn-format/edn
In On the complexity of JSON serialization (2020)

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.