HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
stuartsierra
component
Clojure2013–2025
stuartsierra / component

component

Managed lifecycle of stateful objects in Clojure

18Distinct people
19Mentions
1Explicit recommenders
2.2KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Managed lifecycle of stateful objects in Clojure

GitHub

Where it is used

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

What people are saying

Stuart Sierra's Component: https://github.com/stuartsierra/component and his 'reloaded' workflow: http://thinkrelevance.com/blog/2013/06/04/clojure-workflow-r... I haven't…

lsh used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

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, 3:56:07 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 year19 dated mentions

Observed mentions: 2013-11-21 19:12:43 UTC to 2025-10-19 10:20:54 UTC.

01232013-01-01 00:00:00 UTC to 2014-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments20132014-01-01 00:00:00 UTC to 2015-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 1 mentions; 1 submissions, 0 comments2016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments20192020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 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): 1 mentions; 0 submissions, 1 comments2025

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
20132013-01-01 00:00:00 UTC2014-01-01 00:00:00 UTC110
20142014-01-01 00:00:00 UTC2015-01-01 00:00:00 UTC202
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC110
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC202
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC101
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC312
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC202
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC202
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC101
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
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 UTC101

What Hacker News says

19 sources
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]
> 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 agree with the main sentiment from the article. Although I do think they are discussing Inversion of control more-so than dependency injection. One of my first languages was .net and I was never able to really understand DI in that context that well. Actually using javascript and ducktyping made me understand what it actually was. I remember a .net job interview where I had to write a micro-service and opted to construct the dependency graph in the main function initialising "all" the classes there. Instead of discussing the pro's and con's of that approach they berated me for not using a DI framework (No I did not land that job, but in hindsight it was the most expensive job interview I've ever had. The room was filled with 8 developers going over my code). The main thing the article glosses over is state. something people with a funct
Read the rest
ional background hide from. But if you look at something like the httpclient in .net. I think it took the .net world like 10 years to start using the httpclient properly. Scope and lifetime of those kind of objects are important. managing connection pools, retry state, throttling or the incoming http request. DI does make that kind of thing easieR (I'm not saying it makes it better) Look at clojure's component(https://github.com/stuartsierra/component), I'm not a clojure expert by far. But it is kinda DI/IOC in a functional language. In closing we can agree that it is underused in the right places and overused in the wrong ones.
In Printf(“%s %s”, dependency, injection)
I’m thinking a SQL console mostly qualifies per the article’s idea of a repl. The break loop concept isn’t perfect there though. I’ve always liked the python repl, breaking out a django repl and being able to manipulate the db via the api always felt like a super power to me when coupled with the expressiveness of basic python but last year i started dabbling with Clojure. My first “real” repl driven development experience. 2 things stood out for me: 1. You end up with some genuinely useful executable documentation and it just makes sense to me to preserve some of what i did in the repl while developing. I saw this first here: https://github.com/stuartsierra/component/blob/master/dev/ex... 2. Integration with your editor is essential - having a keystroke to send a form to the repl or evaluate in-line is a real productivity boost. It’s lik
Read the rest
e writing code while an intelligent debugger is permanently live. You don’t need to wait for a compiler run then parse the feedback, it’s just instant in-line runtime feedback. “Paredit” is really sweet. I used calva in vs code for this and tbh it’s as attractive as the language in some ways. I have no idea how to meaningfully apply those concepts to something like python or javascript though. They just don’t lend themselves to that kind of structural editing.
In On Repl-Driven Programming
I’m a beginner clojurian but i’ve noticed some devs put a repl folder in their source tree, e.g. stuart sierra’s component project has a dev sub folder https://github.com/stuartsierra/component/tree/master with repl examples in addition to the tests. I missed a trick in life, i started getting into Clojure in 2020 but about 5 years ago i used to sit 1 row of desks away from Stuart Sierra in Stirling and I don’t think i ever properly spoke to him save for hello or so. It was a funny setup in that operation, i had to fight for my small team to even have office space at the time!
In Rust for Clojurists (2015)
In the Clojure world, this used to be a popular way to structure backend apps: https://github.com/stuartsierra/component > Components provide some basic guidance for structuring a Clojure application, with boundaries between different parts of a system. Components offer some encapsulation, in the sense of grouping together related entities. > Each component receives references only to the things it needs, avoiding unnecessary shared state. Instead of reaching through multiple levels of nested maps, a component can have everything it needs at most one map lookup away.
In A Thought Experiment: Using the ECS Pattern Outside of Game Engines
I might be damaged from years of Java, but my main imagined issue with Clojure is the lack of a component system. Call it OCaml functors or OOP classes, but instantiating a component with replaceable components as input is what I personally need for large scale programming. To make things more concrete, let's say you are writing an integration to another system using HTTP. On the surface you'll have functions like `fetch-album-information` and they will internally use a HTTP client. How do you handle TLS configuration, HTTP connection pooling, etc. and make the function testable and lifecycle-managed to allow clean shutdown? The easy answer is to parameterise the function with another function that takes care of all of that. But that function will need to come from somewhere and I imagine threading these kind of functions explicitly throu
Read the rest
gh your entire program will make it less than palatable. The alternative of using globals that can be replaced in testing carry all the usual problems that global variables have but seems to be what many settle with judging from Clojure code on GitHub. It seems like others are feeling this pain and have invented band-aid solutions like https://github.com/stuartsierra/component but this is something I think needs a first-class solution to encourage this kind of programming.
In Why Clojure?
> Can you be specific? I would love to understand which type of problem you are speaking about. As someone who also got into Swift because it is the only game in town for iOS, it's become my go-to language for everything from tooling/orchestration to back-end infrastructure simply because I find it very nice to work with. Sorry I tried to look through my browser history for a specific example but couldn't find one... All I found was a page on AlamoFire (https://stackoverflow.com/questions/29131253/swift-alamofire...) that I think I was looking up when trying to help debug some iOS mobile code. I think I was looking over the shoulder of an iOS dev on my team and just didn't like the code I was seeing... I also saw an SO thread on JSON parsing in swift (https://stackoverflow.com/questions/24013410/how-to-parse-a-...) so maybe I was annoyed
Read the rest
with how seemingly not-easy parsing JSON into a known class was? might make sense with the AlamoFire thing). I don't think I can defend that point very well but it's just a feeling I've held on to over time. > Admittedly I'm not an expert in Rust, but the best way to explain why I prefer working in Swift is that I find it to be a permissive language, where Rust is an opinionated language. Well I'm not either -- I've been writing it for fun but it's not my main workhorse at this point (nevermind finding a corporate codebase in it). This might make it a bit clearer were we differ -- I'm really into opinionated/not-permissive languages right now. The more feedback I can get from a compiler/type system the better as far as I'm concerned as long as the language lives up to it's promises to make me better/safer/whatever (for Rust & Haskell they mostly deliver). > Swift, by contrast, has deep toolbox which you can use to implement OO patterns, functional patterns, Protocol Oriented design etc. I personally don't actually want OO design in backend languages I use if I can avoid it -- I've found that a good type system along with typeclasses(haskell)/traits(rust)/protocols(swift)/duck-type interfaces(golang) and basic structs is all I need. If the language allows constraints on the generics (i.e. requiring one typeclass/trait/protocol to satisfy another) that's all the composability I need without all the OO boilerplate and cruft. Swift might be the more flexible language since it doesn't have the ownership/borrowing system but I also don't feel like I spend my time reaching for too many design patterns per say -- maybe I write too many of the same kind of application (backend web services). I generally use the component model (like in https://github.com/stuartsierra/component), sprinkle some DDD and I'm good to go for most things. > So I think Swift and Rust have slightly different goals, and where the worst piece of Rust code you can write which will compile will be a bit safer/more performant etc than similar with Swift, to me Swift strikes that balance where it's still giving me a huge advantage over most languages in terms of compile-time checking, but I can be incredibly productive and expressive. Personally the langauge (if you can call it that) which fits this mold for me is Typescript. Of course Javascript is the wild wild west where the most reckless code seems to be written but Tyepscript gives me just enough of a type system and some assurance that everything isn't going to break at runtime. The projects where I'd use node (basically so I can ensure smooth hand off to another developer) I can't use Swift, and the projects where I might use Swift I'd rather use Rust or Haskell. I think the biggest difference is that I don't write Objective-C/Swift iOS apps, if I was maybe I'd have a chance to give Swift a more thorough look over. That said, I basically never intend to write fully native apps because I'd rather pick "close-enough"/"good-enough" options like Nativescript.
In I Do Not Like Go
For the data processing tasks my go-to tool is Manifold[1]. Depending on how the application is structured, you can keep state in atoms, the system map when using Component[2] or vars with Mount[3]. Manifold streams asynchronously join the state transformations together while allowing control over backpressure and threading. On the data analysis side things aren't rosy on the JVM. I'd delegate that part to something which actually has all the tools built-in, e.g. Julia/Python+Numpy/R. Apache Arrow[4] is a nice project to facilitate the dataframe interop. [1] https://github.com/ztellman/manifold [2] https://github.com/stuartsierra/component [3] https://github.com/tolitius/mount [4] https://arrow.apache.org/
In A Year in Clojure

Showing the 15 most recent of 19 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.