Frontend: Scala.js and Laminar | Backend: Scala JVM and Http4s | Protocol: Smithy4s | Build system: Scala CLI and Vite | Packaging: Docker | Web server: NGINX
This is an opinionated fullstack scala template:
- The frontend-backend interaction layer is handled through Smithy4s protocol definition – this ensures shared modelling and keeps all definitions in sync, additionally allowing for code sharing between frontend and backend
- Scala CLI is used everywhere. While it doesn't have multi-module support
- NGINX is used as a web server. Using a very configurable and battle-tested server from the very beginning can help implementing more complicated features later as the app grows. We also use it to serve static assets separately from the JVM backend.
- Vite and TailwindCSS are used on the frontend. Bundling a CSS framework can be helpful to get the styling off the ground for people not usually involved in frontend design work.
- Frontend: Node.js and NPM, Scala CLI
- Backend: Scala CLI
- Protocol code: Coursier, Scala CLI
Scala CLI doesn't have any support for multi-module projects, so to make sure we can work with this codebase in Metals we need to generate BSP definitions manually.
- Run
make setup-ide
and then cross your fingers that Metals will pick everything up correctly
If you have mprocs enabled, you can just run mprocs
at
the root of this project and it will start:
- Live reload of backend
- Live reload of frontend
- Live regeneration of smithy files
Note that when Scala CLI runs in watch mode it will not pick up new files that you add - which will be the case with new smithy4s definitions. So if you get compilation errors, just restart the relevant process so it can pick up new files.
- Make changes to
shared/protocol.smithy
- Run
make smithy4s
- This will regenerate all the code that can be used by both backend and frontend
- Run
make run-frontend
- Note that to perform any actions that execute API calls, you need to have backend running as well
- Run
make run-backend
- This will run the backend server on port 9999 – which is where Vite's frontend tooling expects it to be
- Run
make docker
- Note that this project is organised as a self-contained docker image - just running
docker build .
will produce a working docker image. This is particularly useful for services like Fly.io which detect a Dockerfile and can build and deploy app directly from it