An introduction to handling nested data with Specter

Want to be a :mage: when handling nested data?

Specter is a library for Clojure/ClojureScript that makes it simple to navigate through and change nested data. It’s a ‘swiss army knife’ for handling complex data structures.

With it you can:

  • Query values in a nested structure
  • Change each key or value in a nested map
  • Change each value in a nested sequence
  • Append or prepend values in a nested map or sequence
  • Add (or remove) a value at a specific place in a map or sequence

I’ve written a general introduction to using Specter for navigating, querying and changing nested data. It’s aimed at beginners/intermediates and works through some different examples.

Specter is amazing, well worth the time to learn it. My article is really just scratching the surface … there are more advanced capabilities to discover! Feedback welcome - maybe use-cases not covered?


I’d love to hear some real-world use cases where this came in handy. I haven’t come across any deeply nested structures in a while, and I love hearing war stories. :wink:

At my previous job, I had to work with measurement data (WebRTC QoS metrics) that needed to be aggregated into a deep hierarchical structure. At the lowest level, there were measurement data, on top of that there were quality of experience estimates for each media stream, then for combined audio-visual quality, and so on, with several end-points to be considered at each level, and metadata for performing root cause analysis when things went south, quality-wise. Flattening this structure didn’t make sense, from the point of view of the computations needed, but handling it with the vanilla Clojure functions would’ve been a nightmare. With Specter, the whole thing boiled down to taking the original structure, sticking it inside a thread-last form, and performing a level-wise calculation with Specter’s transform at each step. It turned out to be much clearer and simpler, I think.

Getting to the point that it was comfortable to write the paths did take some time, though.

In my current job I’m using it in simpler cases, but with a similar premise. I have a tree with a couple of levels, and need to update leaves or internal nodes, or sometimes rename keys. I’ve found that for these cases it’s a great tool.