A Scala 3 web framework

Your data model is the source of truth.

Declare a model, and Eezo derives tables, forms, and HTTP routes. Server-side rendering with functional, direct-style Scala. Fast dev feedback, deploys with one command.

Install the command line

curl -fsSL https://eezo.io/install | bash

Needs JDK 25 and sbt. Read the script first if you like.

  • Scala 3
  • JDK 25
  • Postgres
  • MIT
case class Book(
    id: Id[Book],
    title: String,
    author: String,
    pages: Int
) derives Table, Form, Resource
  • GET/books
  • GET/books/new
  • POST/books
  • GET/books/:id
  • GET/books/:id/edit
  • PUT/books/:id
  • DELETE/books/:id

0 clicks

This box is a live component: Component[State] on the server, events up and patches down over websocket, with no JS needed.

Four kinds of docs

How it works

  1. 1
    eezo new myUnicorn

    Scaffold

    A Main, one route, plus build files. Nothing to configure.

  2. 2
    eezo dev

    Serve

    Restarts on save. A broken compile keeps the old code serving.

  3. 3
    eezo deploy

    Ship

    Stages the jars, builds the image, migrates, waits for health.

Check out a full dev cycle in the deploy walkthrough.

What you get

  • One declaration

    derives Table, Form, Resource

    Declare your model, and Eezo derives its tables & database API, its HTML form and all CRUD HTTP routes from one case class.

  • The filename is the route

    app/Health.scala mounts GET /health

    Your own routes come from the file layout. You can override a derived route on the same path.

  • Direct style

    Request => Response

    A handler is a function. Eezo runs on virtual threads, so feel free to block on the database, call an API, or return a page.

  • Migrations from the model

    eezo freeze, then eezo migrate

    Eezo detects schema diffs as you change your data model. Commit them to fingerprinted SQL migrations. On deploy they run before the new code takes traffic.

  • Live pages

    Component[State]

    Write UIs with a Scala functional DSL. State lives on the server, and the browser gets a thin client. UI sends events, server renders UI. No need for JavaScript.

  • Guarded by declaration

    given Owned[Post, User] = ...

    Control route protection, and get your owner type if successful (e.g. a user). In an application with a guard, a route that says nothing is a compile error.

Take the layers you need

An application has a database layer, an http layer, or both. Import the right artifact for your app.

Ready when you are.

Eezo is pre-release: dev is ongoing, and the source is open.