Skip to content

Getting Started

λ Cosmos is a modular Go framework for building HTTP applications. It is organized as four independent modules that compose together:

  • contract — Interfaces for cache, database, sessions, encryption, hashing, events, and hooks. Zero dependencies.
  • router — A generic HTTP router built on top of Go’s http.ServeMux.
  • problem — An implementation of RFC 9457 (Problem Details for HTTP APIs).
  • framework — The application layer that ties everything together with error-returning handlers, middleware, and concrete implementations.

The dependency hierarchy is intentionally simple:

contract (zero deps)
router (standalone)
problem (standalone)
framework → router, problem, contract

Most applications import the framework package directly. The lower-level modules are available when you need just routing or problem details without the full framework.

Each module has its own Go module path under github.com/studiolambda/cosmos. Install the modules you need:

go get github.com/studiolambda/cosmos/framework

This pulls in router, problem, and contract as transitive dependencies. If you only need individual modules:

go get github.com/studiolambda/cosmos/router
go get github.com/studiolambda/cosmos/problem
go get github.com/studiolambda/cosmos/contract

λ Cosmos requires Go 1.25 or later.

A minimal λ Cosmos application creates a router, registers handlers, and starts an HTTP server:

package main
import (
"net/http"
"github.com/studiolambda/cosmos/contract/response"
"github.com/studiolambda/cosmos/framework"
)
func main() {
app := framework.New()
app.Get("/", func(w http.ResponseWriter, r *http.Request) error {
return response.JSON(w, http.StatusOK, map[string]string{
"message": "Hello, Cosmos!",
})
})
http.ListenAndServe(":8080", app)
}

A few things to notice:

  1. Handlers return errors. Unlike http.HandlerFunc, Cosmos handlers return error. This enables centralized error handling — if a handler returns an error, the framework converts it into a Problem Details JSON response automatically.
  2. Response helpers. The contract/response package provides functions like response.JSON, response.HTML, response.String, and response.Stream so you don’t have to manually set headers and encode data.
  3. The router is an http.Handler. You can pass it directly to http.ListenAndServe or any standard Go HTTP server.

When a request arrives:

  1. The router matches the URL against registered patterns using Go’s http.ServeMux under the hood, with support for path parameters like /users/{id}.
  2. The matched handler runs inside a hooks-aware response writer that tracks lifecycle events (before write, before write header, after response).
  3. If the handler returns an error, the framework inspects it:
    • If the error implements http.Handler (like problem.Problem), it calls ServeHTTP directly.
    • If the error implements HTTPStatus() int, that status code is used.
    • Otherwise, a 500 Problem Details response is generated.
  4. If no response was written by the handler, a 204 No Content is sent automatically.
  5. After-response hooks run after the response is complete — useful for logging, metrics, and cleanup.
  • Routing — Route patterns, groups, and the builder API.
  • Handlers — Error-returning handlers, hooks, and the response writer.
  • Middleware — Built-in middleware for logging, recovery, CSRF, and more.
  • Problem Details — Structured error responses following RFC 9457.