Scala + sbt
Category: Tech Stack · Areas: all
Description
Category
tech-stack
Areas
all
Slot
language-runtime
Components
- Language: Scala 2.x (pinned per project)
- Build system: sbt with
sbt-dynverfor git-tag-based versioning - Formatter:
scalafmt - Linter / refactoring:
scalafixwithOrganizeImports - Testing: ScalaTest (primary)
- Effect system: ZIO (where applicable)
- Versioning:
sbt-dynverwith-SNAPSHOTsuffix for dirty/non-tagged commits
Constraints
- All code must pass
scalafmtCheckAll(zero diff) - All code must pass
scalafixAll OrganizeImports - No uncommitted changes should reach CI with a clean version string
- Concurrent task limits: derived from CPU count (
(nproc / 2) - 1, min 2) - Remote build cache:
pushRemoteCacheToconfigured for incremental CI builds - Library dependency schemes must be explicit to avoid eviction noise
When to use
Existing Scala projects on the sbt ecosystem. New Scala services should
evaluate ZIO + sbt as the default stack. Note: projects actively migrating
from Scala to TypeScript should prefer typescript-bun for new code and
maintain scala-sbt only for the remaining Scala surface.
Artifact Impact
Selecting this concern requires these artifacts to change (a selected concern absent from them is drift):
- ADR: Scala + sbt (scalafmt, scalafix, ScalaTest, ZIO where applicable) as the language-runtime
- TD: sbt-dynver versioning, format/lint gates, build-cache and concurrency conventions
Practices by activity
Agents working in any of these activities inherit the practices below through runtime work context, such as a DDx bead context digest.
Requirements (Frame activity)
- Identify whether the project is greenfield Scala or has a migration plan to another runtime
- If mid-migration, scope new work to the target stack and minimize new Scala surface
Design
- Organize as an sbt multi-project build; each logical module is a subproject
- Depend on ZIO for effect management, ZIO JSON for serialization where applicable
- Define portable contracts at service seams to enable incremental migration
Implementation
- Format before commit: run
scalafmtAll+scalafixAll OrganizeImports(or the combined alias) - Use
sbt-dynverfor versioning; do not hardcode version strings dynverSeparator := "-"for Docker compatibilitypackageTimestamp := Package.gitCommitDateTimestampfor reproducible artifacts- Exclude
.bloop,.cache,.targets,.hydra,.metalsfrom IDE indexing
Testing
- Framework: ScalaTest
- Property-based: ScalaCheck (if used)
- Run:
sbt test - CI: separate unit and integration suites; integration tests may require Docker services
Quality Gates (pre-commit / CI)
sbt scalafmtCheckAll— format checksbt scalafixAll OrganizeImports— import organizationsbt test— unit test suitesbt compile— compile all subprojects
Dependency Management
- Declare in
project/Dependencies.scalaorbuild.sbtwith explicitlibraryDependencySchemesfor version conflicts - Use
VersionScheme.Alwayssparingly (only for known-safe upgrades) - Remote cache:
pushRemoteCacheToreduces incremental CI time
Innsigle seal: model-primary by HELIX
The signature covers the markdown source of this page, not these HTML bytes. This page quotes that seal; verify it against the source file.
- Composition
- model-primary
- Issuer
- HELIX
helix - Signing key
ed25519:b0865d76d834a52c48506414d16f4e5a(build key)- Signed source
concerns/scala-sbt.md- Signed
- 2026-09-23T14:11:58Z
- Content digest
sha256:41215faa…7624526e
This build key is endorsed by the human key for build signing; the signature is not a detector and not a truth guarantee.
Raw attestation JSON
{
"payload": {
"innsigle": "1",
"type": "https://innsigle.dev/claim/colophon/v1",
"issued_at": "2026-09-23T14:11:58Z",
"issuer": {
"id": "helix",
"name": "HELIX",
"key_id": "ed25519:b0865d76d834a52c48506414d16f4e5a",
"key_url": "https://documentdrivendx.github.io/helix/.well-known/innsigle/keys.json"
},
"subjects": [
{
"uri": "https://documentdrivendx.github.io/helix/concerns/scala-sbt/",
"digest": {
"alg": "sha256",
"value": "41215faa4db2a33ee755635f86845d43c119a08736d537e0a9fa0c887624526e"
}
}
],
"colophon": {
"schema_version": "1",
"composition": "model-primary",
"ingredients": [
{
"kind": "model",
"name": "Claude",
"role": "draft"
},
{
"kind": "tool",
"name": "sloptimizer",
"role": "rewrite"
},
{
"kind": "human",
"name": "operator",
"role": "structure-edit"
}
],
"notes": null
}
},
"payload_encoding": "json",
"signatures": [
{
"key_id": "ed25519:b0865d76d834a52c48506414d16f4e5a",
"alg": "ed25519",
"sig": "JAtfoXNNyMw5PxtxIi-qzwVejXmMofWP3kJZ_hoU61vctz56cRJusUqo-UTG4L9MsJP_XIZJeUuZvWGlbod_DA",
"signed_at": "2026-09-23T14:11:58Z"
}
]
}