Skip to content

hoota/gossr-kotlin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 
 
 

Repository files navigation

GOSSR Core — Good Old Server‑Side Rendering for Kotlin

What is this module?

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())
}

What problems does it try to solve?

This module exists because of long‑standing pain points in classic server‑side rendering solutions:

❌ Template languages are not refactor‑safe

Renaming a field, method, or model property often silently breaks HTML templates.

❌ Templates are string‑based

IDs, CSS classes, URLs, and parameter names are usually duplicated as strings.

❌ Tooling is weak

IDE navigation, refactoring, and static analysis work poorly across template boundaries.

❌ Logic leaks into templates

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

What does GOSSR Core provide?

  • 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

What does it intentionally NOT do?

This is the most important part.

❌ This is NOT a web framework

No routing, no controllers, no HTTP abstractions.

❌ This is NOT a template engine

There are no templates, no parsing step, no runtime expression language.

❌ This is NOT a frontend framework

No virtual DOM, no reactivity, no client‑side state management.

❌ This is NOT a replacement for CSS or JavaScript

GOSSR generates HTML. Styling and client behavior are separate concerns.

❌ This is NOT tied to Spring (or any other framework)

This module has zero framework dependencies.


Design goals

  • Minimal dependencies

    • kotlin-stdlib-jdk8
    • kotlin-reflect
    • org.jetbrains.annotations
  • Predictable behavior

    • No magic
    • No code generation
    • No annotation processing
  • Longevity

    • Designed for long‑lived projects
    • Resistant to entropy and template rot

Performance and GC considerations

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.

Where does this module fit?

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

Philosophy (short version)

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.


Why Kotlin for UI rendering?

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.

Why not Thymeleaf / JSX / classic templates?

GOSSR Core does not exist because existing solutions are bad.
It exists because they make different trade-offs.

Why not Thymeleaf / FreeMarker / Mustache?

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.


Why not JSX / frontend frameworks?

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

Why not templates at all?

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.


Summary

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.

License

MIT

About

Good Old Server Side Rendering for Kotlin

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages