sbt is recursive

build.sbt conceals how sbt really works. sbt builds are
defined with Scala code. That code, itself, has to be built. What better
way than with sbt?

The project directory is another build inside your build, which
knows how to build your build. To distinguish the builds,
we sometimes use the term proper build to refer to your build,
and meta-build to refer to the build in project.
The projects inside the metabuild can do anything
any other project can do. Your build definition is an sbt project.

And the turtles go all the way down. If you like, you can tweak the
build definition of the build definition project, by creating a
project/project/ directory.

This technique is useful when you have a multi-project build that’s getting
large, and you want to make sure that subprojects to have consistent dependencies.

When to use .scala files

In .scala files, you can write any Scala code, including top-level
classes and objects.

The recommended approach is to define most settings in
a multi-project build.sbt file,
and using project/*.scala files for task implementations or to share values,
such as keys. The use of .scala files also depends on how comfortable
you or your team are with Scala.

Defining auto plugins

For more advanced users, another way of organizing your build is to
define one-off auto plugins in project/*.scala.
By defining triggered plugins, auto plugins can be used as a convenient
way to inject custom tasks and commands across all subprojects.