Self-hosted service
softwaremill/bootzooka avatar
softwaremill/bootzooka

Bootzooka: a Scala service template with the plumbing already done

Template project to quickly start developing a Scala-based microservice or web application, with the build & project structure provided

787 stars148 forksTypeScriptApache-2.0

At a glance

What is it?
Bootzooka is a template project from SoftwareMill that gives you a Scala backend on Postgres with an OpenAPI contract, an Angular frontend wired to generated service stubs, OpenTelemetry instrumentation and a Docker Compose stack for local development. It is Apache-2.0 licensed, and the interesting part is the contract between the two halves rather than either half alone.
Who is it for?
Adopt Bootzooka if you are starting a Scala backend with an Angular or similar frontend and want the build, observability and contract plumbing in place on day one. Do not adopt it if your stack is not Scala, or if you would rather own the CI, the linting and the deployment manifests than inherit them.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What a template is supposed to save you from

Bootzooka is a scaffolding project to allow quick start of development of a microservice or a web application, and the README is direct about the pitch: if you would like to have a jump start developing a Scala-based project, skipping the boring parts and focusing on the real business value, this template might be for you.

So what are the boring parts? The README answers that question indirectly through the structure of the project, which is the most useful thing to read before deciding. There is a backend directory, a ui directory, a project directory with the sbt build definition, a build.sbt at the root, a helm directory for Kubernetes packaging, a docs directory, and separate startup scripts for each side in both shell and batch form.

The split into backend and ui is the core idea, and so is the fact that they are not just two directories that happen to sit next to each other. The backend exposes an OpenAPI description, and the frontend consumes generated service stubs from it. The README states that when there are new or changed endpoint definitions, the OpenAPI description will be regenerated, which is then used by the frontend to generate service stubs.

That is a contract-first workflow, and it is the reason to pick this template over assembling a bare sbt project and an Angular app. The cost is that you inherit a specific stack: Scala with sbt on the backend, Angular on the frontend, Postgres underneath, and OpenTelemetry for traces and metrics.

The project metadata records TypeScript as the primary language, which reflects the Angular side, and the topics list angular, scala and skeleton. The licence is Apache-2.0, with the LICENSE file at the repository root, and the copyright runs to SoftwareMill for 2013 to 2025.

SoftwareMill also offers commercial support for Bootzooka and related technologies, and development services, which tells you something about where the template comes from and who maintains the stack around it.

The Docker Compose stack and the telemetry it wires up

The fastest way to see the project running is the provided Docker Compose setup, and the README says it starts three images: Bootzooka itself, either locally built or downloaded, a PostgreSQL server, and Grafana LGTM for observability.

The compose file shows the shape of that stack. The bootzooka service uses the image softwaremill/bootzooka:latest, maps port 8080 to 8080, and depends on bootzooka-db. Its environment is the interesting part, because it is where the operational decisions are visible:

yaml
    environment:
      SQL_USERNAME: 'postgres'
      SQL_PASSWORD: 'b00t200k4'
      SQL_DBNAME: 'bootzooka'
      SQL_HOST: 'bootzooka-db'
      SQL_PORT: '5432'
      API_HOST: '0.0.0.0'
      OTEL_EXPORTER_OTLP_ENDPOINT: 'http://observability:4318'
      OTEL_EXPORTER_OTLP_PROTOCOL: 'http/protobuf'
      OTEL_SERVICE_NAME: 'bootzooka'
      OTEL_METRIC_EXPORT_INTERVAL: '500' # The default is 60s, in development it's useful to see the metrics faster

The SQL_ variables are the standard database connection settings, and the OTEL_ variables configure the OpenTelemetry exporter to send to the collector over http/protobuf on port 4318, which is the OTLP HTTP endpoint. The metric export interval is set to 500 milliseconds with a comment explaining that the default is 60 seconds and that in development it is useful to see the metrics faster. That is a small thing that tells you the project is tuned for local development rather than for a demo.

The observability service is the grafana/otel-lgtm image, which is Grafana with the OpenTelemetry, Prometheus, Loki and Tempo stack bundled in one image, exposed on port 3000. The comment in the compose file names all four components, which is the OpenTelemetry LGTM stack.

The database service is postgres:17.5 with its own port mapping to 25432 on the host, deliberately different from the 5432 the backend expects inside the network, and its credentials are duplicated from the SQL_ block above.

One thing to notice: the compose credentials are literal values in the file. That is fine for a local template and is exactly what you would change first when you take it into a real environment.

Running the backend and the frontend separately

The development mode path is the one you will use once you start changing things, and the README splits it into three steps.

First, a PostgreSQL database. One option is to start one with Docker, and the command creates a database named bootzooka:

sh
# use "bootzooka" as a password
docker run --name bootzooka-postgres -p 5432:5432 -e POSTGRES_PASSWORD=bootzooka -e POSTGRES_DB=bootzooka -d postgres

Then the backend, which needs the JVM 21 or later and SBT installed:

sh
SQL_PASSWORD=bootzooka ./backend-start.sh

The password is passed as an environment variable at launch, which means the script reads it from the environment rather than from a file. The README also notes that by default OpenTelemetry is disabled, to avoid telemetry export exceptions, and that it is available and explorable if you are using the Docker Compose setup, with the instruction to edit the startup script if you have a collector running.

That default is a good one to copy. A local developer without a collector should not see export errors on every request, and the telemetry stays one environment variable away.

The backend starts on http://localhost:8080, and the API docs are browsable through the Swagger UI at http://localhost:8080/api/v1/docs. The backend also restarts automatically when any source file changes.

Then the frontend. It needs the yarn package manager, installed with the system package manager or with the script the README gives:

sh
curl -o- -L https://yarnpkg.com/install.sh | bash

You then create a ui/.env file based on ui/.env.example, and the default value is fine unless you changed the backend port. The frontend starts with:

sh
./frontend-start.sh

and you open http://localhost:8081. It reloads automatically on changes, and it connects to the backend on the 8080 port as specified in the environment file.

Taking the template into your own repository

The README gives three steps for using Bootzooka as a template for your own project, and they are worth reading closely because step three is the one people miss.

The first is to clone the repository without history, using git clone --depth 1. The second is to switch the git origin to the new repository with git remote set-url origin pointing at your own URL. The third is to rename the project and the package, for example with sbt "renameProject com.mycompany avocado".

The depth 1 clone matters for more than repository size, because a template repository's commit history is noise in your project. A shallow clone gives you a single commit containing the template, and your history starts from your own first commit rather than from a fork of someone else's sbt project.

The sbt renameProject call is the interesting one, because renaming a Scala project is not a single file edit. The sbt plugin used here renames the package declaration across the whole source tree and updates the build definition, which is exactly the tedious part you would otherwise do by hand with a find and replace that has to be right about which directories are source and which are generated.

The rest of the repository is what a mature template looks like in practice. There is a .mergify.yml for merge automation, a .scala-steward.conf so dependency updates arrive as pull requests, a .scalafmt.conf and a .scalafix.conf for formatting and lint rules, a .editorconfig, a .git-blame-ignore-revs so that mass reformatting commits do not pollute blame, and a helm directory for Kubernetes deployment manifests. There are also the .bat variants of both startup scripts for Windows.

The two Scala ecosystem tools are worth a sentence each. scala-steward keeps dependencies current by opening pull requests rather than leaving you to guess which library moved, and scalafix enforces rules that scalafmt cannot, such as migration rules for deprecated APIs. Both are configured in files at the repository root, which means they run in your copy too.

The documentation at softwaremill.github.io/bootzooka dives deeper into architecture, the tech stack and development tips, and the README points there for project info.

What you inherit, and what it costs you

The honest accounting has to include the parts of the template that are not optional.

The first cost is the stack. Scala with sbt on the backend, Angular on the frontend, Postgres as the store, OpenTelemetry for observability. That is a defensible combination and it is one SoftwareMill knows well, but it is a decision, and every additional technology in a template is a decision you inherited rather than made.

The second cost is the generated stubs. The value of the OpenAPI round trip is that the frontend never drifts from the backend, because the service stubs are regenerated from the contract. The cost is that changing an endpoint is a two step operation, change the definition, wait for the description to regenerate, and the frontend types follow. For a team that likes contract-first development, that is the appeal. For a team that would rather hand write its HTTP client, it is ceremony.

The third is the local development setup. The backend needs JVM 21 or later and SBT, the frontend needs yarn, and the database needs Docker or a local Postgres. The scripts paper over this, but the dependencies are real and a new contributor needs all of them before they can see anything running.

The fourth is what the template cannot give you, and it is worth saying plainly. There is no authentication, no authorisation, no multi-tenancy, no rate limiting, no migration story beyond whatever the sbt setup provides, and no deployment pipeline beyond the helm manifests. A template gives you a starting point, and the parts of an application that are product specific are precisely the parts a template cannot guess.

The alternatives differ in what they hand you. Generating a project with an sbt template gives you a Scala build and nothing else, so you assemble the rest yourself. Using the same team’s other templates avoids the mismatch between the pieces. And writing the setup by hand, which is slower at the start and produces something your team fully understands, is sometimes the better trade for a service that will live for years.

The judgement, then, is about how much you want to think about. Bootzooka is a good answer for a team that wants to talk about their domain model on day one and a poor answer for a team that would rather own every layer of the stack.

On maintenance, the repository is not archived and the last push was on 2026-10-20, with a CI workflow badge for Bootzooka CI. There are no GitHub releases, so the template is tracked by its commits, which is how a template that is cloned rather than installed tends to be versioned.

Editorial conclusion

Adopt Bootzooka if you are starting a Scala backend with an Angular or similar frontend and want the build, observability and contract plumbing in place on day one. Do not adopt it if your stack is not Scala, or if you would rather own the CI, the linting and the deployment manifests than inherit them. Verify first that the generated OpenAPI stubs cover the endpoints you change, that the Docker Compose stack matches your deployment target, and that the local development scripts work with the JVM and Node versions you actually have.

Frequently asked questions

What is Bootzooka?

It is a scaffolding project from SoftwareMill for a Scala-based microservice or web application, providing the build and project structure so a team can skip the boilerplate and focus on business logic. It pairs a Scala backend with an Angular frontend over a Postgres database.

How do I run Bootzooka locally with Docker?

Use the provided Docker Compose setup, which starts three images: Bootzooka itself, a PostgreSQL server, and the Grafana LGTM stack for observability. The compose file maps the backend to port 8080, the database to 25432, and Grafana to 3000.

How do I start the Bootzooka backend and frontend separately?

Start a Postgres database first, then run the backend with `SQL_PASSWORD=bootzooka ./backend-start.sh` which needs JVM 21+ and SBT, and it serves on http://localhost:8080 with Swagger UI at /api/v1/docs. For the frontend, create ui/.env from ui/.env.example and run `./frontend-start.sh`, then open http://localhost:8081.

How do I turn Bootzooka into my own project?

Clone the repository without history using `git clone --depth 1`, point the origin at your own repository with `git remote set-url origin`, and rename the project and package, for example with `sbt "renameProject com.mycompany avocado"`.

How does the Bootzooka frontend know about backend endpoints?

The backend regenerates its OpenAPI description when endpoint definitions change, and the frontend uses that description to generate service stubs, so the two sides do not drift apart.

What license is Bootzooka released under?

Apache-2.0, with the LICENSE file at the repository root and the copyright held by SoftwareMill for 2013 to 2025. The repository also ships helm manifests, scala-steward and scalafix configuration, and shell and batch startup scripts for each side.

Official sources

  1. Issues
  2. License: Apache-2.0
  3. Project website
  4. README
  5. softwaremill/bootzooka on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/softwaremill-bootzooka.svg)](https://hysenlabs.com/projects/softwaremill-bootzooka)

Was this useful?