You need a supervision tree, if the application itself spawns processes, where it’s responsible for their lifecycles. If on the other hand your application only defines processes to be started/managed by the user then it doesn’t need a supervision tree on its own. The latter is often needed if processes need runtime user input to be started, but should still be statically defined and not run as children of a dynamic supervisor.
If you take ecto as an example:
The repo is always a userland process, not started/manged by ecto (the application). If that would be the only thing ecto needs, its application wouldn’t need a supervision tree.
But there is Ecto.Application and it starts a supervision tree, because ecto uses a registry where repos are registered in. This one is not needed or wanted to be managed by users of ecto, so the ecto application starts/manages the registry. It also can be started without needing user input.