Overview
Lichess consists of two main build systems:- Scala backend: Built with sbt (Scala Build Tool)
- TypeScript frontend: Built with a custom build system based on esbuild
Building the Backend
sbt Console
The primary interface for building the Scala backend is the sbt console.Starting sbt
- Validates Java installation
- Creates default config files if missing
- Launches sbt with configured JVM options
The
.sbtopts file configures JVM memory:-J-Xms2g: Initial heap size (2GB)-J-Xmx8g: Maximum heap size (8GB)-J-Xss2m: Thread stack size (2MB)
Common sbt Commands
Module-Specific Builds
Compile specific modules:Compilation Order
Thebuild.sbt defines module dependencies. sbt compiles modules in order:
- Level 1: core, coreI18n
- Level 2: ui, common, tree
- Level 3: db, room, search
- Level 4: memo, rating
- Level 5+: Feature modules (game, user, tournament, etc.)
Incremental Compilation
sbt uses incremental compilation:- Only changed files are recompiled
- Dependent modules are recompiled if needed
- Compilation state is cached
Production Packaging
Create a production distribution:target/universal/ containing:
- Compiled classes
- Dependencies
- Startup scripts
- Configuration
Building the Frontend
Build Script
Theui/build script handles all frontend compilation:
Build Options
Building Specific Packages
Build only specific UI packages:Build Process
The build script performs these steps:Build Output
Build artifacts are written to:Watch Mode
In watch mode, the build system:- Monitors source files for changes
- Rebuilds affected packages incrementally
- Updates the manifest
- Prints success/error messages
Full Build
To build everything from scratch:Development Build Workflow
For active development:Edit Scala or TypeScript files. Both build systems will automatically detect changes and recompile.
Internationalization Build
Translations are compiled during the sbt build:translation/source/ are serialized to binary format.
Optimization
Backend Optimization
sbt uses:- Incremental compilation: Only changed files
- Parallel compilation: Multiple modules at once (when possible)
- Dependency caching: Downloaded dependencies cached locally
Frontend Optimization
esbuild provides:- Fast bundling: Written in Go, highly parallelized
- Tree shaking: Removes unused code
- Minification: Smaller file sizes (production mode)
- Code splitting: Shared chunks across modules
- Source maps: For debugging (development mode)
Production Optimizations
- Minification
- Dead code elimination
- Optimized chunk splitting
- Smaller source maps (or none)
Build Performance
Improving sbt Performance
-
Allocate more memory in
.sbtopts: -
Use sbt server: Keep sbt running, don’t restart
-
Build specific modules:
Improving UI Build Performance
-
Build specific packages:
-
Use watch mode: Incremental rebuilds are faster
- Upgrade Node.js: Newer versions are faster
CI/CD Builds
GitHub Actions builds Lichess on every commit:.github/workflows/ for the complete CI configuration.
Troubleshooting
sbt Out of Memory
.sbtopts:
UI Build Fails
Compilation Errors
Slow Builds
- Check system resources (CPU, RAM)
- Close other applications
- Use module-specific builds
- Keep sbt running (don’t restart)
Next Steps
- Learn about testing your builds
- Understand the module structure
- Explore UI development workflow

