HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
metosin
malli
Clojure2019–2026
metosin / malli

malli

High-performance data-driven data specification library for Clojure/Script.

13Distinct people
17Mentions
0Explicit recommenders
1.8KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

High-performance data-driven data specification library for Clojure/Script.

GitHub

Where it is used

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

What people are saying

No recommendation phrase was found in the indexed comments.

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 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 5:04:57 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 year17 dated mentions

Observed mentions: 2019-10-07 09:50:11 UTC to 2026-03-09 09:21:31 UTC.

012342019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20222023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 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
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC202
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC303
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC312
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC202
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC404
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC202
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

What Hacker News says

17 sources
The top-level README gives a bit better idea. Armed with that the explanation might sound a bit more understandable. I'm not familiar with the project (or Clojure), but let me try to explain! > Mycelium structures applications as directed graphs of pure data transformations. There is a graph that describes how the data flows in the system. `fn(x) -> x + 1` in a hypothetical language would be a node that takes in a value and outputs a value. The graph would then arrange that function to be called as a result of a previous node computing the parameter x for it. > Each node (cell) has explicit input/output schemas. Input and output of a node must comply to a defined schema, which I presume is checked at runtime, as Clojure is a dynamically typed language. So functions (aka nodes) have input and output types and presumably they should try to
Read the rest
be pure. My guess is there should be nodes dedicated for side effects. > Cells are developed and tested in complete isolation, then composed into workflows that are validated at compile time. Sounds like they are pure functions. Workflows are validated at compile time, even if the nodes themselves are in Clojure. > Routing between cells is determined by dispatch predicates defined at the workflow level — handlers compute data, the graph decides where it goes. When the graph is built, you don't just need to travel all outgoing edges from a node to the next, but you can place predicates on those edges. The aforementioned nodes do not have these predicates, so I suppose suppose the predicates would be their own small pure-ish functions with the same as input data as a node would get, but their output value is only a boolean. > Mycelium uses Maestro state machines and Maestro is a Clojure library for Finite State Machines: https://github.com/yogthos/maestro > Malli contracts Malli looks like a parsing/data structure specification EDSL for Clojure: https://github.com/metosin/malli > to define "The Law of the Graph," providing a high-integrity environment where humans architect and AI agents implement. Well, beats me. I don't know what is "The Law of the Graph" and Internet doesn't seem to know either. I suppose it tries to say how you can from the processing graph to see that given input data to the ingress of the graph you have high confidence that you will get expected data at the final egress from the graph. I do think these kind of guardrails can be beneficial for AI agents developing code. I feel that for that application some additional level of redundancy can improve code quality, even if the guards are generated by the AI code to begin with.
In Claude built a system in 3 rounds, latent bugs from round 1 exploded in round 3
> There is no way to know what's being passed around without reading the source of the whole chain. But that's not what a Clojure dev would do. 1) We use Malli [0] (or similar) to check specs and coerce types if needed at every point. Checks can be left on in production (I do), or disable–up to you. 2) If the coercion is difficult, use something like Meander. [1] 3) If even that isn't straightforward and you need actual logic in the loop, use Specter. [2] 4) If you're not sure what going on at intermediate steps, use FlowStorm [3]. 5) But you're going to be processing a lot of data you haven't seen before! Use, Malli with test.check [4] and make use of property-based testing with generators. None of this is "advanced" Clojure, this is bread-and-butter stuff I use every day. 6) Need a Notebook-like experience to get better visualization of
Read the rest
intermediate data? Use Clerk [5]. 7) Need special checks on API usage within your codebase? Use clj-kondo [6] with custom linters. They're less than 10 lines each. Unlike default-mutable languages, or typed, it's safe and easy to use libraries with Clojure and they tend to have very little churn. Total opposite from Python or JavaScript (if you're used to that). It's almost impossible to give the impression of what it is like to develop with Clojure if you've only ever used languages with static typing, or languages from the Algol family. Honestly, I hated Clojure's syntax at first BECAUSE I COULDN'T READ IT, and I loathed "structural editing." After 2-3 weeks, I read it just fine and it's hard to remember I ever couldn't do so. Now I like it, and structural editing makes it so easy to change your code, I couldn't live without it at this point. Basically, all my "fears"/dislikes were unfounded—it was a skill issue on my part, not a problem with Clojure. [0] https://github.com/metosin/malli [1] https://github.com/noprompt/meander [2] https://github.com/redplanetlabs/specter [3] https://www.flow-storm.org/ [4] https://github.com/clojure/test.check [5] https://clerk.vision/ [6] https://github.com/clj-kondo/clj-kondo
In Why Clojure?
Spec isn't really essential to Clojure, and most people use Malli nowadays which is very actively developed https://github.com/metosin/malli I see the fact that there isn't much happening with the language as a positive myself. I want the core language to be small and stable. The big difference with Clojure and most languages is that it makes it far easier to implement new semantics in user space. It has a powerful macro system and new ideas can be expressed using libraries instead of having to be baked into the core language itself. Most language grow through accretion as usage patterns change over time. New end up features end up getting bolted on to facilitate that, and the language keeps growing. The problem here is that the scope of things people have to know keeps growing as a result. Meanwhile, Clojure managed to stay small and foc
Read the rest
used, while different kinds of ideas are expressed using libraries. When a new idea comes along people can just use a new library, and they don't have to learn about all the previous libraries that worked differently. I think this is a huge benefit from user perspective.
In Why Clojure?
The Clojure's approach is to favour libraries over frameworks. We use Clojure on various style of applications (mainly web and API based), hosted on widespread infrastructure technologies of Cloud Providers (Kubernetes, PostgreSQL, Kafka, etc.) and it's a breeze: here are our reasons for choosing Clojure https://defsquare.com/blog/why-we-bet-on-clojure If you want to look at libraries where some people have settled, here are our _opinionated_ takes on libraries that we use on almost every project: - HTTP: Ring is the de facto way to manage HTTP request (see https://github.com/ring-clojure/ring/wiki/Concepts) supplemented with various "Middlewares" for web-related concerns (security, logging, content encoding, etc. see https://github.com/ring-clojure/ring/wiki/Standard-middlewar...). Jetty and Aleph are common web servers (and https://gith
Read the rest
ub.com/clj-commons/aleph) that implement Ring interface. - Routing: Reitit (https://github.com/metosin/reitit) - Single-Page App: shadow-cljs for the build concerns (https://github.com/thheller/shadow-cljs), Reagent with Re-frame for complex/large app (https://reagent-project.github.io and https://github.com/day8/re-frame). Even if we now prefer using HTMX (https://htmx.org) and server-side rendering (Hiccup way of manipulating HTML is just amazing, https://github.com/weavejester/hiccup). - Schema management: Malli (https://github.com/metosin/malli) - Lifecycle management: Mount, Integrant or Component (https://github.com/tolitius/mount https://github.com/weavejester/integrant and https://github.com/stuartsierra/component) - Config management: Aero (https://github.com/juxt/aero) and environ (https://github.com/weavejester/environ) - Log: μ/log (https://github.com/BrunoBonacci/mulog) - Time: https://github.com/juxt/tick - Testing: https://clojure.github.io/clojure/clojure.test-api.html and Kaocha for the runner (https://github.com/lambdaisland/kaocha). - Package and project management: tools.deps is simple and powerful (https://clojure.org/guides/deps_and_cli) For infrastructure stuff (PostgreSQL, Keycloak, Solr, Kafka, etc.), just wrapping the underlying Java library or driver is often enough, and there are lots of wrappers for easing the integration. And we implement Hexagonal architecture style to put all of that in place. Don't be afraid a libraries not moving a lot recently, it's a sign that the library is mature and battle-tested. Clojure is a joy to use every day :)
In A History of Clojure (2020) [pdf]
Clojure's lazy sequences by default are wonderful ergonomically, but it provides many ways to use strict evaluation if you want to. They aren't really a hassle either. I've been doing Clojure for the last few years and have a few grievances, but overall it's the most coherent, well thought out language I've used and I can't recommend it enough. There is the issue of startup time with the JVM, but you can also do AOT compilation now so that really isn't a problem. Here are some other cool projects to look at if you're interested: Malli: https://github.com/metosin/malli Babashka: https://github.com/babashka/babashka Clerk: https://github.com/nextjournal/clerk
In Critique of Lazy Sequences in Clojure
Datomic's "immutable database + Datalog" was definitely the biggest source of inspiration but XTDB has a lot of differences - I wrote this FAQ entry up a few years back: https://docs.xtdb.com/resources/faq/#comparisons (note this comparison is for XTDB 1.x and Datomic On-Prem only, so needs revisiting!) Arguably the biggest difference is that XTDB has a schemaless, dynamic core. Having a sane schema is of course important when building complex things, but we believe that the flexibility to experiment with schema (fully) in userspace is essential for moving the state of the art forwards. For instance a lots Clojure users these days prefer relying on https://github.com/metosin/malli for _all_ their schema needs.
In XTDB 2.x Early Access
Any large codebase can be broken up into small isolated components that can be reasoned about independently. This is how you structure Clojure projects if you want them to be maintainable. Clojure inherently encourages doing this by defaulting to immutability. The contract between components is the data being passed to the component and returned by it. Using Malli schemas at the edges of the components is a typical approach to documenting their APIs https://github.com/metosin/malli I see the fact that people often end up creating large and tightly coupled monolithic codebases in static languages as a negative aspect of static typing. Such codebases are difficult to reason about even if you have guarantees that the types align. Ultimately, you need to understand the relationships in code, and how they relate to business logic. The more cou
Read the rest
pling an application has the harder it becomes to reason about it as a whole. Ideally, I think applications should be structured as a bunch of Lego blocks that can be composed together. Each component should encapsulate some functionality, and then the flow of the business logic should bubble up to the top and expressed in how these components are chained together.
In Clojure 15th Anniversary: A Retrospective
> When revisiting old projects I have seen countless of Clojure dependencies having died in the meantime. I have replaced utility libraries with more recent utility libraries sometimes several times. Very annoying. Yes, the "best in class" libraries change every few years in Clojure's universe, but they always bring huge improvements that require completely new APIs. For instance: https://github.com/plumatic/schema -> https://github.com/metosin/malli https://github.com/juxt/bidi -> https://github.com/metosin/reitit https://github.com/bhauman/lein-figwheel -> https://github.com/thheller/shadow-cljs https://github.com/stuartsierra/component -> https://github.com/weavejester/integrant https://github.com/technomancy/leiningen -> https://github.com/practicalli/clojure-deps-edn > So overall Clojure is in a strange situation. For picking it up o
Read the rest
n-the-job its not the responsible choice probably for most situations I work in. For my private tinkering the JVM dependency feels just a little too heavyweight. I don't see that Clojure will hit an inflection point of adoption in any way in the future that would make it a viable candidate for me to use at work. I think about programming languages as tools for different bottlenecks. – Computational: Rust – Networking: Go – Business logic: Clojure / Python And for many people Python has everything that Clojure is missing: a very low barrier to enter, and a very stable and well-documented ecosystem of frameworks and libraries.
In Clojure needs a Rails
I don't really like 'Component'. I seems very clunky and we had a lot of issues with it and a lot incidental complexity in our codebase (now converted to Java). It was the first real system that did these sort of things but if I start a project now, I much rather use Integrant or Clip. https://github.com/weavejester/integrant https://github.com/juxt/clip I haven't used Clip a lot yet but my next project is defiantly going to be with Clip. For validation I have started to use Malli (https://github.com/metosin/malli). I really liked the idea behind clojure.spec but some of the implementation was a bit clunky and a bit too 'Rich Hickey', not sure how to describe it otherwise. Schema was again the first serious attempt at a library like that for Clojure so it was really nice when it came out. Malli sort of combines what is great about both.
In Tour of our 250k line Clojure codebase

Showing the 15 most recent of 17 sources. Enable JavaScript to search and browse every indexed mention.

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.