While learning about dependencies, I became aware that there is a concept of an application in Elixir that differs from what I think of as an application. So I went and read about what an application in Elixir is.
Elixir takes the concept of an application from Erlang. An application in Elixir is like a component. It consists of a group of modules that can be run on their own and can have their own configuration. Applications can have their own dependencies and can be a dependency for another application. A project defines a single application. Since reusable libraries in Elixir are packaged separately, they are their own applications.
When I typically think of as an application, I don't think of a framework or a library, which is a collection of code that does nothing on its own. I think of a runnable piece of code like a web application, desktop application, operating system process, web service, etc. In Elixir, however, reusable libraries and runnable applications are all considered applications.
In Elixir (and Erlang), applications work together to produce what we humans would regard as an application. Elixir applications can be started and stopped individually, which helps with error recovery and robustness. One application can be restarted without bringing down all the other applications that are working with it. Very simple Elixir applications can exist on their own, but as soon as your application uses a dependency, then what you think of as a single application is actually multiple Erlang VM applications working together.
It's almost like Elixir/Erlang libraries are their own independent living things rather that just something that gets merged with other code to form a single thing. I'm starting to think of the Erlang VM as a container that contains a bunch of microservices that talk to each other within the VM environment. It's like looking into a box and seeing a little self-contained version of the bigger world. This seems to fit nicely into the whole philosophy of Elixir and Erlang, which emphasize lots of independent and composable pieces. It's a strange concept to get used to and I'm only starting to get a vague understanding of it.
From what I've read, dependencies in earlier versions of Elixir, being their own applications, needed to be explicitly started. Nowadays, mix will start them automatically.
I'm sure that there's more to managing applications than what I've learned so far, and I suspect that this concept helps makes Elixir applications more robust and resilient.