Clojure DSL resources
This is a curated list of mostly mature and/or actively developed Clojure resources relevant for dealing with domain-specific languages, in particular parsing and data transformation with/of DSLs. The list is currently being expanded as I explore this area more thoroughly. Suggestions are welcome in the form of pull requests or Github issues. I try to steer around abandonware, though.
If you're interested in graphs and data modelling, be sure to check out clojure-graph-resources too.
Domain-specific languages
Lisp dialects traditionally make heavy use of macros to rewrite source code at compile time, opening the DSL floodgates. Somewhat unique to Clojure is a strong emphasis on using the core data literals to form DSLs. In either case, a supposed DSL could just as easily be considered a creative use of existing language features or a particularly well-designed API.
Data-based DSLs
- weavejester/hiccup: Hiccup is a library for representing HTML in Clojure.
- lambdaisland/hiccup: Enlive-backed Hiccup implementation; behaves closer to how Hiccup works in Reagent.
- noprompt/garden: Garden is a library for rendering CSS in Clojure and ClojureScript.
- BrianChevalier/radiant: Write full featured CSS as Clojure data structures, inline.
- stathissideris/dali: Build SVG graphics using a Hiccup-like DSL.
- cgrand/enlive: A selector-based (ร la CSS) templating and transformation system for Clojure.
- seancorfield/honeysql: SQL as Clojure data structures.
- yetanalytics/flint: A Clojure(Script) DSL for creating SPARQL query and update strings.
- wotbrew/relic: Functional relational programming for Clojure(Script).
- cljfx/cljfx: Declarative, functional, extensible wrapper of JavaFX inspired by the better parts of react and re-frame.
- thlack/surfs: Surfs renders Slack blocks, elements, and composition objects from vectors.
- lambdaisland/regal: Regal lets you manipulate regular expressions as data.
- AbhinavOmprakash/luna: Wield the power of regex with the readability of English.
- riverford/datagrep: grep for data, for quick and dirty filtering at the repl.
- QikLiang/GraphQL-format.clj: For building GraphQL queries and transforming the output data in a declaritive format in the style of Meander.
- plumatic/schema: A Clojure(Script) library for declarative data description and validation.
- metosin/malli: Data-driven Schemas for Clojure/Script.
- green-coder/minimallist: A minimalist data driven data model library, inspired by Clojure Spec and Malli.
- kwrooijen/gungnir: A fully featured, data-driven database library for Clojure.
- oakes/edna: A Clojure library for making music with edn data.
- oakes/odoyle-rules: A rules engine for Clojure and ClojureScript.
- oakes/odoyle-rum: What if we used a rules engine to manage all the state of a frontend UI? Can a rules engine replace reframe?
- frankiesardo/minikusari: minikusari is a minimal rule engine built on top of Datascript (and can work with Datomic or Datahike).
- yonatane/bytegeist: Define binary encoding using plain data.
- zen-lang/zen: Zen is a framework to unify Data DSLs, make them composable and take model driven design to the next level.
- sbocq/cronit: A Clojure library to iterate over time points defined by a cron like expression.
- mauricioszabo/spock: Wrappers of SWI and TuProlog in Clojure.
- datalog: See the relevant section in simongray/clojure-graph-resources for a list of libraries.
Data matching/transformation DSLs
Most of these could also be considered data-based DSLs, but I think they deserve a category of their own.
- noprompt/meander: A library that empowers you to write transparent data transformation code that allows you to plainly see the input and output of these transformations.
- juji-io/editscript: A library designed to diff and patch Clojure data structures.
- disalvjn/faconne: Data Restructuring DSL.
- HealthSamurai/ironhide: A runtime agnostic bidirectional data-driven transformation domain-specific language for fun and profit.
- escherize/tracks: Allows the user to create transformations declaratively.
- clojurewerkz/balagan: A tiny library for data structure transformation inspired by Enlive.
- redplanetlabs/specter: Specter rejects Clojure's restrictive approach to immutable data structure manipulation, instead exposing an elegant API to allow any sort of manipulation imaginable.
- xapix-io/matchete: Yet another pattern matching library for Clojure(Script).
- bsless/impedance: Fast, declarative Clojure map transforms to solve impedance mismatch.
- TristeFigure/derrida: Destructuring "Destructuring".
- esuomi/muotti: A graph-based value transformer library.
Traditional Lisp DSLs
- clojure/core.logic: Offers Prolog-like relational programming, constraint logic programming, and nominal logic programming for Clojure.
- quil/quil: Clojure/ClojureScript library for creating interactive drawings and animations.
- overtone/overtone: Overtone is an Open Source toolkit for designing synthesizers and collaborating with music.
- ctford/leipzig: A music composition library for Clojure and Clojurescript.
- ctford/klangmeister: A musical scratchpad. Klangmeister uses Leipzig for all of its music composition.
- cerner/clara-rules: Clara is a forward-chaining rules engine written in Clojure(Script) with Java interoperability.
- clyfe/clara-eav: ClaraEAV is a thin layer over Clara-Rules API that simplifies working with EAV triplets.
- lspector/Clojush: The Push programming language and the PushGP genetic programming system implemented in Clojure.
- adam-james-v/svg-clj: DSL for compiling SVG elements with Clojure(script).
- google/clojure-turtle: A Clojure library that implements the Logo programming language in a Clojure context.
- farrellm/scad-clj: OpenSCAD DSL in Clojure.
- athos/JiSE: JiSE is a Clojure DSL library that compiles a Java-like language into JVM bytecode at macroexpansion time.
- daveyarwood/alda-clj: A Clojure library for live-coding music with Alda.
- latte-central/LaTTe: LaTTe is a proof assistant library based on type theory.
Text-based DSLs
Some DSLs are based on text, but work on Clojure data.
- clj-holmes/shape-shifter: Transforms a string pattern into clojure spec.
- gga/json-path: An implementation of the JsonPath spec for Clojure.
Data-oriented configuration
In most Clojure software there is a guiding principle of data > functions > macros. It has resulted in a convention of using mostly data structures to configure the behaviour of systems. This practice has also led to frequent repurposing of data structures. In many cases, the repurposing crosses into a grey zone somewhere between a DSL and idiomatic use.
- pedestal/pedestal: Pedestal is a set of libraries written in Clojure that aims to bring both the language and its principles to server-side development.
- metosin/reitit: A fast, data-driven router for Clojure(Script).
- juxt/bidi: Bidirectional URI routing.
- juxt/yada: Yada is a web library. Whereas bidi is based on routes as data, yada is based on resources as data.
Honourable mentions
These libraries are not really data-oriented, but can be considered popular mini-DSLs in their own right.
- weavejester/compojure: Compojure is a small routing library for Ring that allows web applications to be composed of small, independent parts.
Parsing
- Engelberg/instaparse: Instaparse aims to be the simplest way to build parsers in Clojure.
- aphyr/clj-antlr: Clojure bindings for the ANTLR 4 parser library.
Parser combinators
- blancas/kern: A Parser Combinators Library for Clojure.
- youngnh/parsatron: Born from Haskell's Parsec library, The Parsatron is a functional parser library.
- rm-hull/jasentaa: A parser-combinator library for Clojure and ClojureScript.
Artificial languages
- davidsantiago/hickory: Hickory parses HTML into Clojure data structures, so you can analyze, transform, and output back to HTML.
- green-coder/html-to-hiccup: An html->hiccup conversion function in pure CLJC.
- yogthos/markdown-clj: A markdown parser that compiles to both Clojure and ClojureScript.
- askonomm/clarktown: A zero-dependency Markdown parser.
- kiranshila/cybermonday: Cybermonday provides a Clojure(Script) interface to working with markdown as a hiccup AST.
- bnbeckwith/orgmode: A Clojure library designed to parse mode files into clojure data structures.
- russellwhitaker/uap-clj: A Clojure library for extracting browser, operating system, and device information from a raw useragent string.
- alumbra/alumbra.parser: An ANTLR4-based GraphQL parser for Clojure.
- igrishaev/remus: An attentive RSS and Atom feed parser for Clojure. It's built on top of well-known and powerful ROME Tools Java library.
- zsau/rome-clj: rome-clj is a Clojure wrapper for ROME, a Java RSS/Atom feed parsing library.
- zsau/id3: A simple ID3v2 parser, written in Clojure.
- l3nz/cli-matic: Compact, hands-free [sub]command line parsing library for Clojure.
- smee/binary: This library is a high performance binary parser combinator.
- lambdaforge/datalog-parser: This parser is used by Datahike and follows the Datalog dialect of Datomic.
Natural languages
Not technically DSLs, but included here to complete the parsing section.
- simongray/datalinguist: A Clojure wrapper for Stanford CoreNLP.
- plandes/clj-nlp-parse: A generalized library to deal with natural language.
- turbopape/postagga: A Library to parse natural language in pure Clojure and ClojureScript.
- ekoontz/menard: A Clojure library for generation and parsing expressions from grammars and lexicons.
Clojure code
- borkdude/sci: Configurable Clojure interpreter suitable for scripting and Clojure DSLs.
- erdos/uclj: A small, quick-starting, native Clojure interpreter.
- clojure/tools.reader: A complete Clojure reader and an EDN-only reader.
- clojure/tools.analyzer: An analyzer for host agnostic Clojure code, written in Clojure and producing AST in EDN.
- borkdude/edamame: Configurable EDN/Clojure parser with location metadata.
- clj-commons/rewrite-clj: rewrite-clj is a library offering mechanisms to easily rewrite Clojure/EDN documents in a whitespace- and comment-preserving way.
- clj-commons/rewrite-cljs: This library is a ClojureScript port of rewrite-clj.
- lread/rewrite-cljc-playground: Working towards rewrite-cljc. Still conservatively pre-alpha, will release on clojars after moving to clj-commons.
- oakes/parinferish: A Clojure and ClojureScript library that parses code and optionally applies parinfer(ish) to it.
- See oakes/html-soup for an example of a library that uses parinferish as a parser.
- carocad/parcera: Grammar-based Clojure(script) parser.
- echeran/kalai: A source-to-source transpiler to convert Clojure to multiple target languages (Rust, C++, Java, ...).
Miscellaneous
- clojure/spec.alpha: The spec library specifies the structure of data, validates or conforms it, and can generate data based on the spec.
- clojure/spec-alpha2: This library is an evolution from spec.alpha as well as work towards several new features.
- jkk/formative: Web forms for Clojure and ClojureScript - rendering, parsing, and validating.
- agentbellnorm/dativity: Dativity is a stateless, data driven workflow engine library for Clojure and ClojureScript.
- clojure-lsp/clojure-lsp: A Language Server for Clojure. Taking a Cursive-like approach of statically analyzing code.
Articles/videos
- Growing a DSL with Clojure
- Parsing XML in Clojure
- Clojure Macros and Metaprogramming
- The Art of Tree Shaping with Clojure Zippers
- Building trees with and without zippers
- Writing Parser Combinator Library in Clojure
- Constructing Clojure private DSLs on top of functions and function combinators
Community
- Clojurians Slack: Where Clojure's most active users seem to hang out.