# FlowStorm records a Clojure execution and lets you walk back through it

> FlowStorm is a debugger for Clojure and ClojureScript that records what a program does and then lets you inspect that execution, through a stepper, a value browser and the REPL. It can be used with a forked Clojure compiler that instruments automatically, or without any fork by re-evaluating forms, and it asks for a JDK 17 toolchain and a compiler swap in your dev aliases.

**flow-storm/flow-storm-debugger** — A debugger for Clojure and ClojureScript with some unique features.

- Repository: https://github.com/flow-storm/flow-storm-debugger
- Stars: 866 · Forks: 38
- Language: Clojure
- License: Unlicense
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/flow-storm-flow-storm-debugger

## Record first, inspect later

FlowStorm is described as an omniscient time travel debugger for Clojure and ClojureScript. The description is unusual but it maps to a specific design.

Instead of stopping at a breakpoint and stepping, the debugger records what happens while the program runs. Once the execution is over, you have a recorded history that you can inspect with several tools, one of which is a stepper. The README's own summary is that FlowStorm records everything that happens when a program runs and then lets you inspect the execution using multiple tools, while integrating with the REPL so that poking at values improves as well.

The reasoning behind it is Clojure specific, and the README spells out the argument. A REPL is a fine tool, but defining function parameters and locals with def for sub-form execution is not easy for complex values. When a function contains loops, maps, filters and anonymous functions, capturing every value for later inspection is hard. Being a dynamic language, running the program in your head is not easy if you are not familiar with the codebase. Adding prints or tap> calls is inconvenient because you have to guess where the problem probably is first, and debug statements have to be typed and removed constantly.

The claim is that some of that can be alleviated by libraries such as scope capture and by tools like portal, reveal and rebl, but that integrating them is not straightforward, and that an integrated debugging system gains more than the sum of its parts.

One more argument is specific to the language. Because Clojure is immutable and expression based, the author argues, you can go beyond REPL poking and stepping.

The licence is the Unlicense, which places the code in the public domain.

## ClojureStorm, the compiler fork that instruments itself

There are two ways to use FlowStorm, and the README marks the first as recommended.

ClojureStorm is a fork of the official Clojure compiler that adds automatic instrumentation, so you do not have to think about which forms to instrument. You use it by swapping the official Clojure compiler for ClojureStorm at dev time, using deps CLI aliases or Leiningen profiles, while keeping your normal compiler for everything else, in particular for tests and production. The fork is a separate repository, flow-storm/clojure, and ClojureScriptStorm is the same idea for ClojureScript, with the ClojureScript compiler forked in flow-storm/clojurescript.

The vanilla route needs no fork at all. You add FlowStorm to your dev classpath and instrument by re-evaluating forms.

The artifacts are published under the com.github.flow-storm group. The complete debugger, which includes the instrumentation library, is:

```clojure
[com.github.flow-storm/flow-storm-dbg "4.8.1"]
```

And the slimmer version, with no GUI, intended for Clojure or ClojureScript remote debugging, is:

```clojure
[com.github.flow-storm/flow-storm-inst "4.8.1"]
```

For the compiler forks themselves, the README lists a Clojure 1.13 build at 1.13.0-alpha6 and a Clojure 1.12 build at 1.12.5-1, and for ClojureScript a 1.12.116 build at 1.12.145-1 and a 1.11.132 build at 1.11.132-9.

## Prerequisites that decide whether it fits your project

The prerequisites are short and they are the first thing to check, because two of them are hard limits.

You need jdk17 or newer. The README points to a section of the user guide for running with jdk11 if you still need that, so older toolchains are possible but they are a documented exception rather than the default.

You need Clojure 1.11.0 or newer. Clojure 1.10 is supported only if you use FlowStorm from source, with a git dependency pointing at the repository and a pinned sha:

```clojure
{:git/url "https://github.com/flow-storm/flow-storm-debugger" :git/sha "..."}
```

That is a real cost for projects still on 1.10, since it means tracking a moving commit instead of a released version.

The second dependency is architectural rather than technical. Swapping the compiler means your dev environment is no longer the same compiler that builds your tests and your production artifacts, and the README is explicit that you are expected to keep both. Any difference between the forked and official compiler therefore becomes a difference between what you debug and what you ship, and keeping that boundary clean is the user's job.

For the ClojureScript side, the compiler fork is a separate concern again, with its own versions listed for ClojureScript 1.12.116 and 1.11.132.

## The repository is a Clojure build with a Makefile on top

The source layout shows how the project is put together. There are separate source directories for the debugger, the instrumentation library and shared code, src-dbg, src-inst and src-shared, plus src-dev, with docs, examples and a tests.edn. The build is defined in deps.edn and build.clj, and the browser side is a shadow-cljs build described by shadow-cljs.edn.

A Makefile wraps the common tasks. The test target runs the Clojure test suite, the lint target runs clj-kondo over the three source trees with the project config, and the docs target builds the user guide with asciidoctorj from the AsciiDoc source.

```bash
clj -M:test:dev unit-clj
clj-kondo --config .clj-kondo/config.edn --lint src-dbg src-shared src-inst
```

Publishing is done with Maven rather than with the Clojure tooling, which is an unusual mix. The install targets call mvn install:install-file against the built JAR and its generated POM, and the deploy targets call mvn deploy:deploy-file with repositoryId clojars and the Clojars URL, so the artifacts land in Clojars through the Maven protocol.

The package.json is not a JavaScript package in the usual sense. It carries only two dependencies, websocket at 1.0.34 and shadow-cljs at 2.23.3, which exist for the ClojureScript compilation and the browser connection.

There is also an llm-prompt.txt at the top level and a directory of example plugins, which tells you that the debugger is meant to be extended rather than only used.

## Recording everything is a deliberate trade

The debugging model has a cost that is easy to gloss over. If the tool records everything that happens when a program runs, then the recording is proportional to the work the program does, and it happens during development on every instrumented execution.

That cost is acceptable in the situations the author describes: chasing a bug, or understanding how something works, whether that is a small expression or an entire codebase. It is a different matter in a long-running process that produces a lot of data, where the recording grows without bound unless you manage it.

The alternative approach has a different shape, and the README names the tools. Scope capture is a library that captures values during execution, and portal, reveal and rebl are tools for exploring complex values at the console. Those are lighter: you opt into capture where you need it and you inspect values in a separate UI. What they do not give you is the recorded history, the ability to move through an execution after the fact, and the integration between the recorded data and the REPL.

The difference is therefore one of instrumentation scope. A capture library instruments the code you point it at. FlowStorm, with ClojureStorm, instruments everything the compiler sees, which is why it can promise a stepper and a full history rather than a set of captured values.

There is a middle path in the documentation too. The vanilla route, adding FlowStorm to the dev classpath and instrumenting by re-evaluating forms, gives you the debugger without the compiler fork, at the cost of the automatic coverage that ClojureStorm provides.

## Versions, tags and what the releases actually say

The version picture needs a careful reading, because the README and the tag list do not agree.

The README names version 4.8.1 as the latest stable release for both the flow-storm-dbg and flow-storm-inst artifacts, and lists the Clojure and ClojureScript fork versions alongside them. The published tags tell a different story: 4.5.4 on 2025-09-09, 4.5.0 on 2025-08-05 and 4.4.3 on 2025-05-21 are the most recent releases visible on GitHub. The last push to the default branch was on 2026-08-21 and the repository is not archived.

In other words, the development line is well past the tags you can see, and the artifacts named in the README are newer than the tagged releases. Anyone pinning a version should pin the one named in the README's artifact list rather than the newest visible tag, and should read the CHANGELOG.md at the top of the repository for what changed between them.

Two version details deserve attention on their own. The Clojure 1.13 fork is published as 1.13.0-alpha6, an alpha of the compiler it tracks, which tells you the 1.13 line is not a settled target. And the ClojureScript fork versions are numbered independently of the ClojureScript versions they extend, so 1.12.145-1 follows ClojureScript 1.12.116.

The licence situation is the simplest part. The Unlicense dedicates the work to the public domain, which removes the attribution and redistribution conditions that a copyleft licence would impose on a debugger you fork to add your own instrumentation.

## Conclusion

Adopt FlowStorm when you work on Clojure or ClojureScript code that is hard to reason about from a REPL session alone, and when you are willing to add a compiler fork to your dev aliases and to record whole executions, which costs time and memory in exchange for a replayable history. Do not adopt it for a project on Clojure 1.10 without building from source, or for a team that cannot accept a JDK 17 requirement. Before you commit, add the flow-storm-inst artifact to a scratch project and try the vanilla route, since that requires no compiler swap, and check the CHANGELOG.md in the repository, because the versions named in the README as the latest stable releases differ from the tags published on GitHub.

## FAQ

### How do I use the FlowStorm debugger with Clojure?

There are two ways. The recommended one is ClojureStorm, a fork of the Clojure compiler with automatic instrumentation, which you swap in at dev time through deps CLI aliases or Leiningen profiles while keeping your normal compiler for tests and production. The vanilla way adds FlowStorm to your dev classpath and instruments by re-evaluating forms.

### What are the prerequisites for FlowStorm?

jdk17 or newer, with a documented route for jdk11, and Clojure 1.11.0 or newer. Clojure 1.10 is supported only when FlowStorm is used from source through a git url and sha dependency.

### Which FlowStorm artifact should I depend on?

The complete debugger, which includes the instrumentation library, is com.github.flow-storm/flow-storm-dbg at version 4.8.1. For remote debugging with no GUI, use the slimmer com.github.flow-storm/flow-storm-inst at the same version.

### Does FlowStorm work with ClojureScript?

Yes. ClojureScriptStorm is the ClojureScript equivalent of ClojureStorm, a fork of the official ClojureScript compiler with automatic instrumentation, published as com.github.flow-storm/clojurescript. The README lists builds for ClojureScript 1.12.116 and 1.11.132.

## Sources

- [flow-storm/flow-storm-debugger on GitHub](https://github.com/flow-storm/flow-storm-debugger)
- [Issues](https://github.com/flow-storm/flow-storm-debugger/issues)
- [License: Unlicense](https://github.com/flow-storm/flow-storm-debugger/blob/master/LICENSE)
- [README](https://github.com/flow-storm/flow-storm-debugger/blob/master/README.md)
- [Releases](https://github.com/flow-storm/flow-storm-debugger/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/flow-storm-flow-storm-debugger
