GOSSR Core is a small, dependency‑minimal Kotlin library for server‑side HTML rendering using pure Kotlin code.
It provides a strictly‑typed, refactor‑friendly DSL for generating HTML into an Appendable (StringBuilder, stream, writer, etc.) without templates, string concatenation, or framework coupling.
At its core, GOSSR is simply:
Kotlin code → HTML output
Nothing more, nothing less.
DIV {
classes("my-css-class")
+"Hello World"
BR()
+formatDateTime(LocalDateTime.now())
}This module exists because of long‑standing pain points in classic server‑side rendering solutions:
Renaming a field, method, or model property often silently breaks HTML templates.
IDs, CSS classes, URLs, and parameter names are usually duplicated as strings.
IDE navigation, refactoring, and static analysis work poorly across template boundaries.
Conditional rendering and formatting logic often end up half‑implemented in a limited DSL.
GOSSR addresses these issues by treating HTML generation as normal Kotlin code:
- Full IDE support
- Compile‑time safety
- Refactoring without fear
- No stringly‑typed contracts
- A lightweight HTML DSL implemented in Kotlin
- Output to any
Appendable - Structured tag hierarchy (
DIV,SPAN,FORM,INPUT, etc.) - Attribute helpers (
classes,id,style, etc.) - Safe escaping
- Full access to Kotlin language features:
if / when- loops
- functions
- extension functions
This is the most important part.
No routing, no controllers, no HTTP abstractions.
There are no templates, no parsing step, no runtime expression language.
No virtual DOM, no reactivity, no client‑side state management.
GOSSR generates HTML. Styling and client behavior are separate concerns.
This module has zero framework dependencies.
-
Minimal dependencies
kotlin-stdlib-jdk8kotlin-reflectorg.jetbrains.annotations
-
Predictable behavior
- No magic
- No code generation
- No annotation processing
-
Longevity
- Designed for long‑lived projects
- Resistant to entropy and template rot
GOSSR Core is designed to keep runtime allocation pressure extremely low.
HTML output is written directly to an Appendable as rendering happens.
There are no intermediate buffers, no virtual DOM, no in-memory tree
representation and no serialization step. Tags, attributes and text nodes
are emitted straight into the output stream without creating temporary
objects on the heap. Even string escaping for attribute values and text
nodes is performed directly into the Appendable, without creating
intermediate strings.
Special attention is also paid to lambda allocations.
This DSL naturally relies on many callback-style parameters, and without
care this would result in short-lived lambda objects. To avoid this,
GOSSR extensively uses inline functions wherever it is appropriate.
Callbacks are inlined and substituted directly into the generated bytecode
at compile time, eliminating unnecessary allocations and reducing GC load.
As a result, rendering cost is very low, predictable and stable even for large pages, making GOSSR suitable for high-throughput server-side rendering and long-running applications.
GOSSR Core is the foundation layer.
If you want:
- framework integration
- typed routing
- Spring MVC support
- forms, CSRF, CSS, and request binding
→ see Gossr for Kotlin & Spring
https://github.com/hoota/gossr-kotlin-spring
This core module is intentionally framework‑agnostic and can be used in:
- custom HTTP servers
- CLI tools
- static site generators
- embedded environments
- or as a building block for higher‑level integrations
HTML is not a template.
HTML is a result of code execution.
GOSSR treats UI rendering as a normal, testable, refactorable Kotlin computation — nothing more.
Using Kotlin as the language for UI rendering means the full power of the language is available when building pages.
You can use constants, collection iteration, ordinary functions that render reusable page fragments, and shared code exactly the same way you reuse business logic. UI blocks can be extracted into functions or base classes, extended or overridden through inheritance, and composed without introducing a separate template language. Control flow is expressed using normal if / else, when, try / catch, and loops — not limited or ad-hoc DSL constructs. As a result, UI code remains readable, testable, and refactor-friendly even as it grows in complexity.
GOSSR Core does not exist because existing solutions are bad.
It exists because they make different trade-offs.
Classic server-side template engines are:
- string-based
- loosely typed or untyped
- parsed at runtime
- weakly connected to the Kotlin codebase
Typical consequences in long-lived projects:
- broken templates after refactoring
- duplicated names (fields, URLs, CSS classes)
- logic split between Kotlin and template DSLs
- limited IDE support compared to real Kotlin code
GOSSR removes the template layer entirely. HTML is generated by ordinary Kotlin code, so refactoring, navigation, and static analysis work exactly as everywhere else in the project.
JSX and modern frontend frameworks solve a different problem:
- rich client-side interactivity
- complex UI state management
- partial page updates
- heavy client-side logic
They introduce:
- build pipelines
- transpilation
- hydration
- runtime overhead
- duplicated validation and contracts between backend and frontend
GOSSR Core is intentionally server-side first. It is designed for:
- SSR pages
- internal tools
- admin interfaces
- data-heavy forms
- environments where simplicity, predictability and correctness matter more than client-side dynamism
Templates look simple at first, but they introduce an extra language and an extra failure mode.
GOSSR follows a different philosophy:
If something contains logic,
it should be written in the main programming language.
No parsing step.
No runtime expression language.
No magic context variables.
Just Kotlin code producing HTML.
| Approach | Primary goal | Trade-off |
|---|---|---|
| Templates | Designer-friendly markup | Weak typing, fragile refactoring |
| JSX / SPA | Rich client interactivity | Complexity, duplication, runtime cost |
| GOSSR Core | Correct, refactor-safe SSR | Less visual, more code |
GOSSR Core chooses correctness, longevity, and explicitness over convenience.
MIT