Files
summercms-initial-research/.planning/research/STACK.md
2026-02-04 02:18:31 +01:00

17 KiB

Stack Research: SummerCMS

Project: SummerCMS - Scala CMF rewriting WinterCMS Researched: 2026-02-04 Overall Confidence: HIGH (all major recommendations verified with official sources)

Executive Summary

The ZIO ecosystem in 2025/2026 is mature and production-ready. ZIO HTTP 3.x is stable, Quill provides excellent PostgreSQL integration, and the tooling ecosystem (Mill, Besom) has reached 1.0 stability. The recommended stack prioritizes developer experience while maintaining the performance goals of the project.

Key finding: The ZIO ecosystem has consolidated around a smaller set of well-maintained libraries, with zio-sql and zio-jdbc deprecated in favor of Quill as the primary database library.


Language & Runtime

Technology Version Purpose Rationale
Scala 3.3.7 LTS Core language LTS provides stability for a multi-year project; 3.8.x requires JDK 17+ which may limit deployment options
JDK 17+ Runtime Required for Scala 3.3.x LTS, widely available, long-term support
ZIO 2.1.24 Effect system Latest stable with stream performance improvements, binary compatibility guaranteed in 2.x line

Confidence: HIGH - Verified via Scala releases, ZIO releases

Notes:

  • Scala 3.3.7 LTS is recommended over 3.8.x bleeding edge - CMF needs stability over newest features
  • ZIO 2.1.x line has explicit binary compatibility guarantees, critical for plugin ecosystem

Core Framework

Technology Version Purpose Rationale
ZIO HTTP 3.8.1 HTTP server/client Production-ready, built on Netty, native ZIO integration, OpenAPI support, built-in template DSL

Confidence: HIGH - Verified via ZIO HTTP releases

Why ZIO HTTP over alternatives:

  • vs http4s: ZIO HTTP is ZIO-native; http4s is Cats Effect-native. Mixing ecosystems adds complexity.
  • vs Akka HTTP: Licensing changes in Akka make it unsuitable for new projects.
  • vs Play: Too heavyweight for a CMF, brings its own conventions that conflict with our plugin architecture.

Key ZIO HTTP 3.x features for CMF:

  • Declarative endpoint definitions (maps to YAML-driven form generation)
  • Built-in OpenAPI generation (API documentation for plugins)
  • Middleware composition (authentication, logging, metrics)
  • WebSocket support (future real-time features)
  • Datastar SDK (new in 3.6.0 - alternative to HTMX, evaluate later)

Database Layer

Technology Version Purpose Rationale
ZIO Quill 4.8.6 Query DSL & ORM-like features Compile-time query generation, ZIO-native contexts, PostgreSQL-specific features
PostgreSQL Driver 42.7.5 JDBC driver Latest version compatible with Quill
HikariCP 5.x Connection pooling Industry standard, ZIO integration via Quill contexts
Flyway 10.x Database migrations Industry standard, straightforward ZIO integration

Confidence: HIGH - Verified via Quill documentation, Quill releases

Why Quill:

  • zio-sql deprecated: Per Ziverge 2025 roadmap, zio-sql and zio-jdbc are deprecated. Quill is the endorsed solution.
  • Compile-time queries: SQL errors caught at compile time, critical for plugin ecosystem stability
  • ZIO contexts: PostgresZioJdbcContext provides native ZIO effect integration
  • ProtoQuill: Full Scala 3 support via zio-protoquill

Installation:

libraryDependencies ++= Seq(
  "io.getquill" %% "quill-jdbc-zio" % "4.8.6",
  "org.postgresql" % "postgresql" % "42.7.5",
  "org.flywaydb" % "flyway-core" % "10.22.0",
  "org.flywaydb" % "flyway-database-postgresql" % "10.22.0"
)

Template Engine

Technology Version Purpose Rationale
ScalaTags 0.13.1 Primary HTML generation Type-safe, 4x faster than Twirl, pure Scala
Twirl 2.0.9 Theme templates (fallback) Familiar syntax for theme developers, Play-compatible

Confidence: MEDIUM - ScalaTags is well-documented; theme developer experience needs validation

Primary approach: ScalaTags

  • Type-safe HTML construction
  • Almost 4x faster than Twirl
  • Pure Scala - IDE support, refactoring works
  • Integrates with ZIO HTTP's built-in template DSL
  • Good for component rendering where type-safety matters

Secondary approach: Twirl for themes

  • Theme developers expect template syntax, not Scala code
  • Twirl's @ syntax is intuitive for non-Scala developers
  • Can be compiled at build time for performance
  • Familiar to WinterCMS/Laravel Blade developers

Hybrid strategy:

  • Core components and admin backend: ScalaTags (developer maintains, type-safety critical)
  • Theme partials and layouts: Twirl (theme developers, simplicity matters)
  • Consider: Custom template language (like Twig) parsed to ScalaTags at compile time

Open question: Should we invest in a Twig-to-ScalaTags compiler for WinterCMS theme compatibility?


Frontend Integration

Technology Version Purpose Rationale
HTMX 2.x (latest) Data-attribute driven interactions Captures OctoberCMS data-attributes spirit, no build step, server-rendered
htmx4s 0.3.0 Scala HTMX integration Type-safe HTMX attributes, ZIO HTTP compatible
Vue.js 3.x Complex interactive components For forms, media manager, admin UI where HTMX insufficient

Confidence: HIGH - htmx4s verified via Scaladex, patterns validated via Rock the JVM demo

htmx4s modules:

libraryDependencies ++= Seq(
  "com.github.eikek" %% "htmx4s-constants" % "0.3.0",    // HTMX vocabulary as Scala values
  "com.github.eikek" %% "htmx4s-scalatags" % "0.3.0",    // ScalaTags integration
  // Note: htmx4s-http4s is for http4s - we'll need ZIO HTTP equivalent
)

HTMX strategy:

  • Primary interaction model for CMS frontend
  • Server returns HTML fragments, not JSON
  • Reduces JavaScript complexity significantly
  • Aligns with OctoberCMS's original data-attributes philosophy

Vue.js strategy:

  • Reserved for complex admin UI components (media manager, form builder)
  • Mounts on specific DOM elements, not full SPA
  • Communicates via JSON API endpoints
  • Themes can declare Vue components for complex interactivity

What NOT to use:

  • Alpine.js: WinterCMS's messy Snowboard+Alpine was explicitly called out as a problem. HTMX is simpler.
  • React/Angular: Overkill for CMS, adds build complexity for theme developers.
  • Full SPA mode: Server-rendered with progressive enhancement is better for SEO and initial load.

Configuration & Serialization

Technology Version Purpose Rationale
ZIO Config 4.0.5 Configuration loading YAML/HOCON support, type-safe config derivation
ZIO Schema 1.7.5 Schema derivation JSON/Protobuf/Avro codecs, form field validation
ZIO JSON 0.7.x JSON serialization Schema-based, high performance

Confidence: HIGH - Verified via ZIO Config docs, ZIO Schema docs

Why ZIO Schema is critical for CMF:

  • YAML-driven forms: Schema can describe form fields, validation rules
  • Automatic codec derivation: Plugin data models get JSON APIs for free
  • Migration support: Schema evolution for plugin updates
libraryDependencies ++= Seq(
  "dev.zio" %% "zio-config" % "4.0.5",
  "dev.zio" %% "zio-config-yaml" % "4.0.5",
  "dev.zio" %% "zio-config-magnolia" % "4.0.5",  // Derivation
  "dev.zio" %% "zio-schema" % "1.7.5",
  "dev.zio" %% "zio-schema-json" % "1.7.5",
  "dev.zio" %% "zio-json" % "0.7.45"
)

Logging & Observability

Technology Version Purpose Rationale
ZIO Logging 2.5.3 Structured logging ZIO-native, SLF4J bridge for Java libraries
ZIO Metrics (ZIO Core) Metrics collection Built into ZIO 2.1, no separate library needed

Confidence: HIGH - Verified via ZIO Logging releases

libraryDependencies ++= Seq(
  "dev.zio" %% "zio-logging" % "2.5.3",
  "dev.zio" %% "zio-logging-slf4j2-bridge" % "2.5.3"  // For Java libs
)

Testing

Technology Version Purpose Rationale
ZIO Test 2.1.24 Core testing Part of ZIO core, property-based testing, test containers
TestContainers 0.41.x Integration tests PostgreSQL containers for database tests

Confidence: HIGH - ZIO Test is part of ZIO Core

libraryDependencies ++= Seq(
  "dev.zio" %% "zio-test" % "2.1.24" % Test,
  "dev.zio" %% "zio-test-sbt" % "2.1.24" % Test,
  "com.dimafeng" %% "testcontainers-scala-postgresql" % "0.41.4" % Test
)

Build & Tooling

Technology Version Purpose Rationale
Mill 1.0.0+ Build tool 3-7x faster than sbt, simpler mental model, better IDE support
Scala CLI 1.x Scripts & utilities Quick prototyping, migration scripts

Confidence: HIGH - Verified via Mill 1.0.0 announcement

Why Mill over sbt:

  • Performance: Native launcher starts in ~100ms, 3-7x faster builds
  • Simplicity: Standard Scala OOP model, not sbt's task/setting matrix
  • IDE support: Jump-to-definition works, easier debugging
  • Zero-install JVM: Launcher can download required JDK
  • Module scaling: Handles hundreds of modules without slowdown (critical for plugin ecosystem)

sbt considered but rejected:

  • Larger ecosystem BUT complex mental model
  • Plugin developers would need to understand sbt deeply
  • Performance degrades with many subprojects (each plugin = subproject)

Mill build structure for plugins:

// build.mill
import mill._
import mill.scalalib._

object core extends ScalaModule {
  def scalaVersion = "3.3.7"
  // Core CMF
}

object plugins extends Module {
  object blog extends ScalaModule {
    def moduleDeps = Seq(core)
    // Blog plugin
  }
  object user extends ScalaModule {
    def moduleDeps = Seq(core)
    // User plugin
  }
}

Deployment

Technology Version Purpose Rationale
Besom 0.5.0 Pulumi Scala SDK Pure Scala IaC, type-safe infrastructure
Docker Latest Containerization Standard deployment format
GraalVM Native Image Optional Native binaries CLI tools, faster startup for serverless

Confidence: MEDIUM - Besom verified via GitHub, production patterns need validation

Why Besom for Pulumi:

  • Pure Scala 3, not Java SDK wrapper
  • Type-safe infrastructure definitions
  • Functional, lazy evaluation semantics
  • Can share types with application code
// Besom dependency (via Scala CLI or Mill)
//> using dep org.virtuslab::besom-core:0.5.0
//> using dep org.virtuslab::besom-aws:6.0.0

Docker strategy:

  • Primary deployment target
  • Multi-stage builds: compile with Mill, run with JRE
  • Consider distroless base images for security

GraalVM Native Image:

  • For CLI tools (scaffolding, migrations)
  • Faster cold starts
  • NOT for main server (reflection in Quill, ZIO may have issues)

Complete Dependency Overview

// build.mill - Mill build file
import mill._
import mill.scalalib._

trait SummerCMSModule extends ScalaModule {
  def scalaVersion = "3.3.7"

  override def ivyDeps = Agg(
    // ZIO Core
    ivy"dev.zio::zio:2.1.24",
    ivy"dev.zio::zio-streams:2.1.24",

    // HTTP
    ivy"dev.zio::zio-http:3.8.1",

    // Database
    ivy"io.getquill::quill-jdbc-zio:4.8.6",
    ivy"org.postgresql:postgresql:42.7.5",
    ivy"org.flywaydb:flyway-core:10.22.0",
    ivy"org.flywaydb:flyway-database-postgresql:10.22.0",

    // Template
    ivy"com.lihaoyi::scalatags:0.13.1",

    // HTMX
    ivy"com.github.eikek::htmx4s-constants:0.3.0",
    ivy"com.github.eikek::htmx4s-scalatags:0.3.0",

    // Config & Schema
    ivy"dev.zio::zio-config:4.0.5",
    ivy"dev.zio::zio-config-yaml:4.0.5",
    ivy"dev.zio::zio-config-magnolia:4.0.5",
    ivy"dev.zio::zio-schema:1.7.5",
    ivy"dev.zio::zio-schema-json:1.7.5",
    ivy"dev.zio::zio-json:0.7.45",

    // Logging
    ivy"dev.zio::zio-logging:2.5.3",
    ivy"dev.zio::zio-logging-slf4j2-bridge:2.5.3"
  )

  override def testIvyDeps = Agg(
    ivy"dev.zio::zio-test:2.1.24",
    ivy"dev.zio::zio-test-sbt:2.1.24"
  )
}

What NOT to Use

Deprecated/Abandoned Libraries

Library Status Use Instead
ZIO SQL Deprecated Quill
ZIO JDBC Deprecated Quill
Akka HTTP License changed ZIO HTTP
Slick Lightbend ecosystem Quill

Wrong Ecosystem

Library Issue Use Instead
http4s Cats Effect-native ZIO HTTP
Doobie Cats Effect-native Quill
Circe Cats-based JSON ZIO JSON
fs2 Cats Effect streams ZIO Streams
Cats Effect Different effect system ZIO

Overkill for CMF

Library Issue Use Instead
Play Framework Too opinionated, heavyweight ZIO HTTP + custom routing
Spring Boot Java-centric, not idiomatic Scala ZIO ecosystem
Tapir Adds abstraction layer we don't need ZIO HTTP declarative endpoints

Frontend Anti-Patterns

Approach Issue Use Instead
Full SPA SEO problems, complex build HTMX + progressive enhancement
Alpine.js WinterCMS's messy pattern HTMX for simple, Vue for complex
Snowboard.js WinterCMS-specific, deprecated HTMX

Confidence Levels Summary

Area Level Notes
ZIO Core (2.1.24) HIGH Production-proven, official releases verified
ZIO HTTP (3.8.1) HIGH Stable 3.x line, verified Feb 2025 release
Quill (4.8.6) HIGH Endorsed as only maintained ZIO RDBMS library
ScalaTags (0.13.1) HIGH Stable, well-maintained by Li Haoyi
htmx4s (0.3.0) MEDIUM Small but functional library, may need custom ZIO HTTP integration
Mill (1.0.0) HIGH Just hit 1.0, production-ready
Besom (0.5.0) MEDIUM Pre-1.0 but stable-candidate, VirtusLab maintained
Template strategy MEDIUM ScalaTags + Twirl hybrid needs validation with theme developers

Open Questions

Requires Further Investigation

  1. Twirl vs custom template language: Should we support Twig syntax for WinterCMS theme migration?

  2. htmx4s ZIO HTTP integration: htmx4s has http4s module but not ZIO HTTP. Need to build adapter or use constants-only module.

  3. Plugin hot-reload: Can Mill's watch mode + ZIO HTTP dev mode enable WinterCMS-like plugin hot-reload?

  4. WebSocket scaling: Project context mentions "websockets scale poorly." ZIO HTTP has WebSocket support - research SSE as alternative for real-time features.

  5. GraalVM native compatibility: Full server as native image may have issues with Quill/ZIO reflection. Validate if important for deployment.

  6. Datastar SDK: ZIO HTTP 3.6+ includes Datastar SDK - evaluate as HTMX alternative for even simpler frontend patterns.

Architecture Decisions Pending

  • Plugin dependency resolution algorithm (WinterCMS uses PHP Composer-like)
  • Theme rendering pipeline (compile-time vs runtime templates)
  • Admin backend component system (Vue vs HTMX vs hybrid)

Sources

Official Documentation

Release Pages

Strategy & Roadmap

Integration Examples


Stack research completed: 2026-02-04