Backend engine · (beta)

Write KDL.
Get a REST API.
Ship it.

Terranova reads a plain KDL schema file and immediately serves a fully functional REST API — no boilerplate, no code generation, no fuss.

Input api.kdl
application "Todo" version="0.1" {
    entity "User" {
        schema {
            pk "id" type="int"
            field "name" type="string"
            field "email" type="string"
            has-many "Todo" as="tasks" on-delete="cascade"
        }
        queries {
            get "user_by_id" sql="SELECT * FROM user WHERE id = :id" {
                param "id" type="int"
            }
        }
        views {
            template "/user" query="user_by_id" html="
                <h1>{{data.name}}</h1>
                <p>Email: {{data.email}}</p>
            "
        }
    }
    entity "Todo" {
        schema {
            pk "id" type="int"
            field "title" type="string"
            field "done" type="bool"
            field "created_at" type="datetime"
            belongs-to "User" as="owner"
        }
    }
    profile "dev" default=true {
        listen address="127.0.0.1" port=8080
    }
}
Generated endpoints
GET/user
POST/user
PUT/user/
DEL/user/?id={id}
GET/user/user_by_id?id={id}
GET/?id={id}
GET/todo
POST/todo
GET/todo/{id}
PUT/todo/
DEL/todo/?id={id}
<5ms
Median response time
0
Lines of boilerplate
100%
OpenAPI compliant
1 file
Your entire API schema

Three steps.
That's all.

No scaffolding commands. No generated directories to maintain. No runtime dependencies beyond Terranova itself.

01 / 03
[kdl]
Write a KDL schema
Declare your entities, fields, types, relationships, queries, and views in a single api.kdl file.
02 / 03
[run]
Run terranova serve -f <filename>
Point Terranova at your KDL file. It parses, validates, creates the SQLite database, and starts serving — in under a second.
03 / 03
[api]
You have an API
CRUD endpoints, custom queries, HTML views, and a live OpenAPI spec are all ready to go.
$ terranova serve -f ./api.kdl

Everything a REST API needs.
Nothing it doesn't.

[db]
SQLite first
Zero‑configuration database. Terranova creates and manages the SQLite file automatically.
sqlite
[→]
Relationships
Declare has-many, has-one, and belongs-to. Terranova creates foreign keys and rules.
relations · intuitive schemas
[≡]
Custom queries
Raw SQL or composed batches. Typed parameters bound automatically from request data.
raw · composed · params
[✓]
HTML views
Bind queries to Mustache templates via inline declaration or external files.
templates · mustache
[↗]
Live OpenAPI spec
Terranova serves an interactive OpenAPI document at /docs.html that stays in sync with your KDL.
OAS 3 · yaml spec
[⚡]
Blazing fast
JIT‑compiled handlers (TCC), yyjson for JSON, internal bytecode Mustache engine. <5ms median, idle <1MB.
low latency · efficient

Less ceremony.
Same result.

[×] Traditional approach
Scaffold a framework project, install dependencies
Define models, migrations, and run them manually
Write controllers, routes, middleware for every resource
Add validation logic by hand in request handlers
Wire up auth per‑route with JWT/session libraries
Manually maintain OpenAPI annotations
Hours before your first endpoint is callable or seconds with AI, then days debugging broken code
[✓] With Terranova
+Write one api.kdl file
+Schema and migrations (coming soon) derived automatically
+All CRUD endpoints generated from entity blocks
+Validation declared inline with field types
+Auth not yet supported (coming soon)
+OpenAPI spec served live, always accurate
+Callable in under 60 seconds

KDL syntax cheat sheet.

KDL (KDL Document Language) is a small, human‑readable node document format. Terranova adds a thin API‑specific vocabulary on top.

Node Example What it does
application application "MyApp" version="0.1" Root container. Sets name, version, license, and global namespace.
entity entity "User" { schema { ... } } Declares a data model. Generates CRUD endpoints and a database table.
pk pk "id" type="int" Defines the primary key column. Required for UPDATE/DELETE endpoints.
field field "name" type="string" optional=true Defines a column. Supported types: int, float, string, bool, datetime, date, blob, file.
has-many/has-one/belongs-to has-many "Todo" as="tasks" on-delete="cascade" Declares relationships. Creates foreign keys and nested routes.
queries get "user_by_id" sql="..." { param "id" type="int" } Custom SQL queries (raw or composed). Each becomes an HTTP endpoint.
views template "/user" query="user_by_id" html="..." Binds a query to a Mustache template. Renders HTML responses.
profile profile "dev" default=true { listen address="127.0.0.1" port=8080 } Environment‑specific server configuration (address, port, TLS).

Your API is
one file away.