Skip to content
Zever
Home

How Zever works

One-page overview of the path from a .zen schema through the compiler and container to swappable adapters.

1 min readEdit on GitHub

Zever turns a .zen schema into typed code at compile time, then wires every backend concern through one container at run time. It generates the plumbing, never your business logic.

compile time run time
------------ --------
schema.zen -> compiler -> generated/ config -> container -> adapters
(dsl) lexer ORM, routes, defaults lazy db, cache,
parser OpenAPI, DDL < file accessors queue, ...
resolver < env Close(ctx)
backends

The two halves meet at generated code only. Your running service imports generated output, config, container, and adapters. It never imports the compiler.

Stage What happens Read more
Schema You describe entities, services, and RPCs in .zen files. Syntax
Compiler Lexer, parser, and resolver turn source into one ir.Schema, reporting every problem in a single run. Resolver and IR
Backends Each backend reads the IR and writes files: ORM bindings, protobuf, OpenAPI, Atlas HCL. Backends
Boundary Compiler packages are compile-time only; runtime packages never import dsl. Compiler boundary
Config Strict, layered defaults < file < env selects an adapter per service. Configuration
Container One per process; each service resolves lazily on first use and closes in dependency order. Container
Adapters Small interfaces with swappable, explicitly registered adapters. Providers and adapters
Process Load, build, resolve on first use, close. Lifecycle
  • Swapping is config. Changing sqlite to postgres or memory to redis edits config, never call sites.
  • No hidden wiring. There are no globals and no init() registration: you call each adapter’s Register() yourself.
  • Compile-time cost, run-time speed. Parsing and resolving happen once, ahead of time, so request-time code stays plain Go.