paulanthonywilson
What’s wrong with Umbrella Apps?
I like Umbrella projects and pretty much always use them for personal Elixir stuff, especially Nerves things.
But I don’t think this is a popular choice. I’ve never really understood why they are disliked. The two arguments I’ve read against them don’t check out for me: you can’t control the order of config loading (yes you can) and they are for deploying things separately (no they’re not).
Admittedly I have never worked on a huge Umbrella project; The massive monoliths I’ve worked on have all had flat architectures.
What issues have people had that has put them off Umbrella Projects?
Most Liked
sasajuric
A few months ago I started consulting on an umbrella project (about 10 apps). The first thing I did was deumbrellization of the project, which brought some benefits:
- about 2k LOC less, due to removal of the repetitive boilerplate across subprojects
- faster test and build times
- simplified folder structure
- better tooling support for simple projects
As an example of the last point, various paths that are printed by mix tasks (e.g. test IIRC) aren’t “clickable” in vscode (I couldn’t click to open the file in the editor), because the printed paths are missing the apps/myapp/ prefix. I found this extremely annoying and disruptive. This alone is for me the reason to avoid umbrella as much as possible.
Generally, my sentiment is that if the subapps are not deployed separately, the umbrella app doesn’t bring anything useful to the table, compared to single project + boundary. Even if boundary is not used, I find the benefits of umbrella don’t justify the issues mentioned above.
pdgonzalez872
I’ll let more experienced folks chime in regarding the technical reasons.
My personal experience from working in a few large umbrella projects (note that this is not due to the tech itself, just what happened with the folks using it) have mostly shown issues with premature and incorrect separation of concerns. This is a human problem, not a tech one. Symptoms of these are having sub-apps called core, core_db, utils… that are required everywhere in a project. Basically, instead of thinking in contexts within a non-umbrella app, folks try (incorrectly) to abstract those into apps. Sometimes, they mean well too.
If you can’t run tests in your sub-app without requiring other apps, you should likely have a flat structure and use contexts instead. If you have issues with dependencies (your own), you should reconsider the structure as well. Folks can use behaviours and define boundaries within the contexts if they are inclined (and get Mox for free out of the box if done properly). If you share the same database and have multiple sub-apps calling into it (and having issues with it), maybe your abstraction is incorrect. It is self imposed complexity most of the time. Some folks just want to do it too, because, they can.
These have been the bad experiences with it. Again, this is not related to the umbrella structure itself, but they did happen with folks that used it because they could.
This reminds me of the hippo story from “Along came Polly”. If you are a hippo, be a hippo. If you are a flat app, it’s ok!
https://www.youtube.com/watch?v=uhOzaH0GbEg
ityonemo
I think by and large the problem is similar to “don’t use GenServers for code organization”. Likewise, often times people use umbrellas to organize their code, when umbrellas are best used when you have deployment heterogeneity (I think).
They are bad for organization because:
- they create an extra layer of indirection in your file paths (apps/ directory)
- it’s easy to wind up with intra-app dependencies that you lose track of.
- grokking the mix.exs paths is tricky
- some libraries don’t support umbrellas
A better solution is to just be unafraid to make top level namespaces in the main app (like how Phoenix creates MyApp and MyAppWeb). For example, I often have a Type module that contains project-specific Typing, and a Tools module, and a Db module.
Popular in Discussions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance








