README.md

March 12, 2026 · View on GitHub

Nova

A web framework for the BEAM
Build fault-tolerant, distributed web applications in Erlang, Elixir, or LFE.

Build Status Hex.pm Docs Slack


Why Nova?

Nova is the web framework for the BEAM. Whether you write Erlang, Elixir, or LFE, Nova gives you the productivity of a modern web framework on the runtime you already trust:

  • Routing, controllers, and views — familiar MVC patterns that map naturally to Erlang modules
  • Plugin pipeline — composable middleware for auth, CORS, logging, and custom concerns
  • WebSockets and Pub/Sub — real-time features backed by OTP's pg module, distributed out of the box
  • Session management — ETS-backed by default, pluggable for custom backends
  • Template rendering — ErlyDTL (Django Template Language) with hot reload
  • OTP-native — your web app is a proper OTP application with supervision trees, hot code upgrades, and releases

Nova runs on Cowboy and supports Erlang, Elixir, and LFE.

Quick start

Install the rebar3 plugin:

# One-line install
sh -c "$(curl -fsSL https://raw.githubusercontent.com/novaframework/rebar3_nova/master/install.sh)"

# Or add to ~/.config/rebar3/rebar.config
{project_plugins, [rebar3_nova]}.

Create and run your app:

rebar3 new nova my_app
cd my_app
rebar3 nova serve

Open localhost:8080 — you're running Nova.

What a controller looks like

-module(my_app_main_controller).
-export([index/1, create/1]).

index(#{method := <<"GET">>} = _Req) ->
    {json, #{message => <<"Hello from Nova!">>}}.

create(#{method := <<"POST">>, json := Body} = _Req) ->
    %% Validate, persist, respond
    {json, #{status => <<"created">>, data => Body}}.

Route it:

routes(_Environment) ->
    [#{prefix => "/api",
       security => false,
       routes => [
           {"/", {my_app_main_controller, index}},
           {"/items", {my_app_main_controller, create}}
       ]}].

Features

FeatureDetails
RoutingPath parameters, prefixes, per-route security, environment-based routing
ControllersReturn {json, Map}, {ok, Variables}, {status, Code}, {redirect, Path}, {sendfile, ...}
PluginsPre/post request hooks — built-in CORS, CSRF, correlation ID, or write your own
WebSocketsFull WebSocket support via nova_websocket behaviour
Pub/SubDistributed messaging via nova_pubsub — channels, topics, broadcast
SessionsETS-backed sessions with pluggable backends
TemplatesErlyDTL (Django-style) with hot reload via rebar3 nova serve
SecurityPer-route security functions for authentication and authorization
Static filesBuilt-in file controller with range request support
ObservabilityOpenTelemetry integration for tracing and metrics
DatabaseKura — an Ecto-inspired database layer for Erlang

Request pipeline

Request → Cowboy → Nova Router → Plugins (pre) → Security → Controller → Plugins (post) → Response

Ecosystem

PackageDescription
novaCore framework
rebar3_novaProject scaffolding and generators
nova_testTesting utilities and request builder
kuraDatabase layer — schemas, migrations, changesets, queries
rebar3_kuraMigration generator for Kura
opentelemetry_novaAutomatic OpenTelemetry instrumentation

Documentation

Requirements

  • Erlang/OTP 23+
  • Rebar3

Community

Contributing

Contributions are welcome! Check CODE_OF_CONDUCT.md and look for issues labeled good first issue.

License

Apache 2.0