> _I think all agreed that Component is the industry standard for managing lifecycle of Clojure applications. If you are a Java developer you may think of it as a Spring (DI) replacement – you declare dependencies between “components” which are resolved on “system” startup. So you just say “my component needs a repository/database pool” and component library “injects” it for you._
[mount](https://github.com/tolitius/mount) was created after using Component for several projects.
While Component is an interesting way to manage state, it has its limitations that prevented us
from having the ultimate super power of Clojure: _fun working with it_. Plus several other disadvantages
that we wanted to "fix".
## So what are the differences?
### Objects vs. Namespaces
One thing that feels a bit "unClojure" about Component is "Objects". Objects everywhere, and Objects for everything.
This is how Component "separates explicit dependencies" and "clears the bounaries".
This is also how an Object Oriented language does it, which does not leave a lot of room for functions:
with Component most of the functions are _methods_ which is an important distinction.
Mount relies on Clojure namespaces to clear the boundaries. No change from Clojure here: `defstate` in one namespace
can be easily `:require`d in another.
### Start and Stop Order
Component relies on a cool [dependency](https://github.com/stuartsierra/dependency) library to build
a graph of dependencies, and start/stop them via topological sort based on the dependencies in this graph.
Since Mount relies on Clojure namespaces and `:require`/`:use`, the order of states
and their dependencies are revealed by the Clojure Compiler itself. Mount just records that order and replays
it back and forth on stop and start.
### Component requires whole app buy in
Component really only works if you build your entire app around its model: application is fully based on Components
where every Component is an Object.
Mount does not require you to "buy anything at all", it is free :) Just create a `defstate` whenever/whereever
you need it and use it.
This one was a big deal for all the projects we used Component with, "the whole app buy in" converts an "_open_" application
of Namespaces and Functions to a "_closed_" application of Objects and Methods. "open" and "close"
here are rather feelings, but it is way easier and more natural to
* go to a namespace to see this function
than to
* go to a namespace, go to a component, go to another component that this function maybe using/referenced at via a component key, to get the full view of the function.
Again this is mostly a personal preference: the code works in both cases.
### Refactoring an existing application
Since to get the most benefits of Component the approach is "all or nothing", to rewrite an existing application
in Component, depending on the application size, is daunting at best.
Mount allows adding `defstates`_incrementally_, the same way you would add functions to an application.
Component changes the way the code is structured. Depending on the size of the code base, and how rich the dependency graph is, Component might add a good amount of cognitive load. To a simple navigation from namespace to namespace, from function to function, Components add, well.. "Components" that can't be ignored when [loading the codebase in one's head](http://paulgraham.com/head.html)
On the flip side, Component _system_ usually requires lots of `:require`s as well, since in order to be built, it needs to "see" all the top level states.
Mount keeps states in namespaces, hence the app becomes "[The One](https://en.wikipedia.org/wiki/Neo_(The_Matrix))", and there can't be "multiples The Ones".
Testing is not alien to Mount and it knows how to do a thing or two:
* [starting / stopping parts of an application](https://github.com/tolitius/mount/blob/master/doc/differences-from-component.md#starting-and-stopping-parts-of-an-application)
* [start an application without certain states](https://github.com/tolitius/mount#start-an-application-without-certain-states)
* and [swapping alternate implementations](https://github.com/tolitius/mount#swapping-alternate-implementations)
But running two apps in the same JVM side by side with "same but different" states, is not something Mount can do at the moment.