Yesterday I released nREPL 1.0. I hadn’t really planned to have the release then, but after cutting CIDER 1.5 (“Strasbourg”) a bit earlier that day, I decided that this was The Day.

nREPL 1.0 is a tiny release in terms of changes and that’s OK. It means we’ve gotten to the point where most of the problems that we set out to address in 2017 have been solved.1 Some highlights:

  • many annoying bugs have been solved
  • the internal architecture has been (massively) improved
  • the nREPL protocol has been extended with some essential functionality like code lookup, code completion. Additionally the Clojure nREPL implementation added some handy dynamic code/middleware loading middleware, that make it easier for clients to configure nREPL to match their expectations.
  • while the documentation is still not great, it’s much better than it was 4 years ago
  • we’ve implemented an EDN transport for the people who don’t like bencode
  • we’ve added native support for Unix sockets
  • most prominent nREPL extensions are now part of the nREPL GitHub organization

The only thing that was missing at this point was the magic “1.0” release to acknowledge all of this.

This was quite the journey and I’m happy that we’ve made it to this massive milestone. If I knew how much work I’d need to put in to make nREPL 1.0 a reality back in 2018, I’d probably wouldn’t have volunteered for this task. But I’m very glad that I did! Working on nREPL was much trickier than working on CIDER in many ways and taught me a lot about patience2 and the value of maintaining backward compatibility. Outside of the initial namespace changes we didn’t break backward compatibility at all! Following in the footsteps of my one of my Clojure Heroes (Chas) wasn’t easy either, as I had quite the shoes to fill!

I’m really glad that mine & Chas’s theory that moving nREPL out of Clojure Contrib would result in more contributions turned out to be correct. We got where we did through the work of many people and I am thankful to all of them! And recently we’ve celebrated the 12th million download of nREPL after it’s development was restarted and I became the project’s maintainer. I hope this means we’re doing something right.

Still, our work is never truly done. Now that 1.0 is out of the way we have to start thinking about what follows next. Recently there were a couple of interesting discussions about missing features and improving the nREPL protocol specification and the ability to test against it. I fully agree that this is where our focus should be going forward. In particular - I think it’s super important to improve the documentation of the specification, so people wouldn’t have to look at the server/client message exchange to figure out how the nREPL protocol works. I’m reasonably sure this will also result in broader adoption of nREPL outside the Clojure community.

I hope that more people will join those interesting conversations and will be willing to help with the work they are going to generate. As usual - contributions are most welcome! Together we brought back nREPL to life and together we can make it even better. I consider the past 4 years to be another great display of the awesomeness of the Clojure community. Keep hacking!

P.S. You can read more about the evolution of nREPL since I took over the project here:

  1. Actually we had addressed quite a few problems in 2018 alone with nREPL 0.4.x and 0.5.x. 

  2. It took a couple of years until most Clojure dev tools moved away fully from the legacy tools.nrepl and embraced the new nrepl/nrepl