This template is opinionated, with many pre-made decisions about which tooling, code style, and workflow to use. If you don't like that, don't use a template.
The primary goal of this template is to provide a starting point for people who want to build a full stack website in Scala, but don't want to spend time setting up the build config and picking out libraries. The reference point for decisions made herein are my own projects and preferences.
Furthermore, this template has only been tested on Windows 11. Other operating systems will likely work, but don't be surprised if platform-specific adjustments are necessary. In case you find yourself having to make adjustments, please consider contributing those adjustments back to the template.
- Everything from
SgtSwagrid/scala-config, including reasonable Scalafmt settings, CI piplines for build integrity, and some IDE config. - A collection of common libraries that work well together (see Dependencies).
- Example build configuration and setup instructions. In particular, this demonstrates how to serve compiled Scala code to the client as a static JavaScript file.
Click 'Use this template' on GitHub, and follow the instructions to create a new repository for your website. All files herein will be copied as-is.
2. Configure build.sbt
You'll need to set the name, organization, and version fields in build.sbt and projectRoot in Subprojects.scala.
You may also wish to set the GH_TOKEN local environment variable and GitHub repository secret (see Environment Variables) to help with agentic and CI workflows.
Secrets can be added from the GitHub web interface by nagivating as follows from your repository's page:
Settings โ Secrets and variables โ Actions
Thereafter, the template should work out-of-the-box, and you can start building your website immediately. If you haven't already, you may also want to read the documentation on Laminar.
The included MIT license should be considered only as part of the template, and is not binding.
This repository is hereby released to the public domain, to be used freely.
In particular, and contra LICENSE.md, you may remove the license text from copies.
CONTRIBUTING.md is also part of the template, and does not necessarily apply to contributions to the template itself.
The most important thing to know is that many of the configuration files are automatically synced from scala-config, and should be updated there rather than here.
Check out scala-library-template for a similar template to quickly start a new Scala library.
In order to locally run or work on this project, you'll need to have the following installed:
- Scala 3* - a functional programming language on the JVM.
- sbt 1.12.4 or newer - the preeminent build tool of the Scala ecosystem (configured in build.sbt).
- JDK 21 - a runtime environment for the JVM (compatibility of JDK 25 is uncertain).
- Git - for version control.
- Node.js - used by the Playwright MCP server for browser automation during development (optional).
*Installing Scala separately isn't strictly required, as the correct version (currently 3.8.2) will be fetched by sbt in the build process. However, it may still be helpful for testing.
git clone https://github.com/SgtSwagrid/scala-website-template.git
cd scala-website-templateThe following commands are defined in Commands.scala:
sbt dev- Hot-reload is enabled by default, meaning the server and client will automatically restart when code changes are detected.
- The local website will be available at localhost:8080.
sbt build- This is not necessary for running a development server, as builds are automatic.
sbt lint- If using IntelliJ, it is advised to instead enable reformat-on-save.
- Linting is also automatically applied when submitting a PR.
- Alternatively use
sbt lint-checkto check for violations without automatically fixing them.
The following environment variables can be set to configure your local instance:
GH_TOKEN- your personal access token (PAT) from GitHub, used by Claude with GitHub's MCP server to interact with GitHub on your behalf, and by the Initialise Repository workflow. Click here to create a new PAT (only allow access to this repository, and disallow all destructive actions). Also add this as a GitHub repository secret namedGH_TOKEN.HOST- the address on which the development server listens for requests (default:localhost).PORT- the port on which the development server listens for requests (default:8080).
While it isn't mandatory, use of the following tooling is advised:
- IntelliJ IDEA - the main IDE for Scala development.
- Claude Code - an AI agent for automating tasks (optional).
Shared configuration for the above is checked into the repository for a seamless experience.
The codebase is partitioned into three subprojects. All subprojects are written in Scala, but they are compiled in different ways. Build configurations for the subprojects can be found in Subprojects.scala.
The server subproject
- Code which is deployed to a JVM-based backend server.
- Responsible for database management and serving HTTP or WebSocket requests.
- This includes providing the client code (see below) to the user.
- All web pages use a single minimalistic template, whose only job is to invoke the (appropriate part of the) client code.
- The primary entry point is found in Main.scala.
The client subproject
- Code which is transpiled to a JavaScript-based frontend and delivered to the user's browser.
- Responsible for the user interface.
- We exclusively use client-side rendering (CSR), meaning that all DOM elements are constructed dynamically by the client.
- All client code is packaged into a single source file (
main.js) by the build system.
The common subproject
- Code which is common to both the server and client. That is, modules in common are freely available to the other subprojects.
- Conversely, code in server or client cannot be referenced by any other subproject.
- Code from common is compiled twice; once into JVM bytecode for the server, and once into JS for the client.
- Used for defining common data types, algorithms, or communication protocols that are (or in principle could be) used by either.
- Avoids source duplication: one implementation is enough.
The following open-source libraries are used. You do not need to install these manually, as they are managed by sbt. Dependencies are defined in Subprojects.scala.
- scalafmt - a code formatter to ensure a consistent style (configured by .scalafmt.conf).
- Tapir 1.13 - a library to define and implement HTTP APIs.
- Netty - an asynchronous web server for the JVM (integrated with Tapir, among other options).
- Swagger - a UI for exploring and testing server endpoints (integrated with Tapir, see localhost:8080/docs).
- Prometheus - for metrics and performance monitoring (integrated with Tapir, not yet enabled).
- asset-loader - for serving static assets.
- Scala.js - the official Scala-to-JS transpiler.
- Laminar 17 - a library for building reactive web-based user interfaces (and extended by laminext).
- Airstream - a functional reactive programming library (required by Laminar).
- Circe - automatic serialisation/deserialisation to/from JSON (for client-server communication).
- Cats - provides abstractions for functional programming (alongside Cats Effect 3 and others).