A type-algebraic framework where your code is pure domain meaning and compilation produces the rest — HTTP, CLI, Telegram, OpenAPI, Pydantic validation, SQL, RFC 7807 errors. All from the shape of your types.
@schema_meta(http_crud("/users", Users))
@dataclass
class User:
id: Annotated[int, Identity]
name: str
email: Annotated[str, Unique, MaxLen(255)]5 REST endpoints. Pydantic models. OpenAPI spec. You write fields, fold writes everything else.
uv add git+https://github.com/prostomarkeloff/emergent.gitFrameworks today scatter meaning across files. A User lives in a model, a serializer, a view, a URL config, a migration, a test fixture — and none of those files know about each other. An LLM (or a human) has to hold the whole graph in their head to make a correct change.
emergent inverts this. Everything about a thing is on the thing:
@schema_meta(
http_crud("/bounties", Board, ops=(LIST, GET, CREATE)),
Methods(),
)
@dataclass
class Bounty:
id: Annotated[int, Identity]
title: str
reward: Annotated[int, Min(0)]
status: Annotated[str, MaxLen(20), Doc("Bounty status"),
cli.Help("Current status"), openapi.Description("Status field"),
sql.Index("idx_status")]
@classmethod
@post("/bounties/{bounty_id}/claim")
async def claim(cls, db: ..., bounty_id: int, hunter: str) -> Result[Bounty, DomainError]: ...One place. Every concern — validation, CLI help text, OpenAPI description, SQL index, HTTP routes — lives as an annotation on the field it belongs to. The fold compiler reads these annotations and produces correct output for each target. No sync bugs. No scattered state. No framework magic to reverse-engineer.
This is locality by construction, and it's what makes emergent work for humans and machines alike.
The entire framework is one function. Compilation, verification, explanation, LLM verification, query execution, derivation, semantic macros — all are the same
foldapplied to different data. Everything else is consequences.
Coding agents are becoming primary authors of production code. But implicit architectures break them — AI-assisted development is often slower on real repos, developers ship AI code they don't fully understand, and refactoring drops dramatically.
The problem isn't the models. It's the code they're asked to work with. Non-local dependencies, implicit global state, and framework magic require understanding the whole program to change one part. LLMs fail at this — compositional reasoning across scattered files degrades fast.
emergent is designed from the ground up so that an agent never needs to understand the whole program. Four structural properties make this work:
| Property | What it means |
|---|---|
| Locality | All concerns for a field/entity live on it. O(1) navigation, zero cross-file dependencies. |
| Defunctionalization | Behavior is frozen data (dataclasses), not functions. Every capability is inspectable, hashable, serializable. |
| Semantic dispatch | Transforms operate on domain meaning (effects), not syntax. A SoftDelete() transform knows what "delete" means across all targets. |
| Composition algebra | Capabilities compose via tuple concatenation (free monoid). All combinations are valid by construction. |
The result: a derivation is ~50 tokens of pure meaning. An LLM doesn't generate boilerplate — it generates intent, and fold compiles intent into code.
emergent's IR reads itself. Every axis has an explain system — structured dicts for tools, human-readable text for you:
explain_schema(User)
# === User ===
# [SchemaName('users')]
#
# id (int):
# [Identity]
#
# email (str):
# [Unique, MaxLen(255)]
# cli: Help('Email address')
# openapi: Description('User email'), Format('email')
# sql: Index('idx_email')
explain_application(app)
# === Application (3 endpoints) ===
#
# Endpoint #1 (2 exposures):
# [POST /api/v1/players] RequestResponseCodec
# request: RegisterRequest, response: RegisterResponse
# [register (cli)] RequestResponseCodec
# request: RegisterRequest, response: RegisterResponse
explain_full(User) # 3-layer trace
# === User (full trace) ===
#
# Schema: 3 fields (1 identity)
# id (int) [Identity]
# name (str)
# email (str) [Unique]
#
# Derivation: 1 pattern
# Pattern #1: Dialect (11 steps), provider=Users
# steps: InspectEntity → RequireIdentity → BindProvider → ...
# ops: List, Get, Create, Update, Patch, Delete
#
# Surface: 6 exposures across 1 endpoint
# GET /api/users [ListUserRequest → ListUserResponse]
# GET /api/users/{id} [GetUserRequest → GetUserResponse]
# ...Schema, query, storage, surface, compilation trace, derivation pipeline — all explainable. No execution, no side effects. The program describes itself from its own IR.
verify catches semantic contradictions before your code runs:
from emergent.wire.verify import verify_raising
@dataclass
class Sensor:
id: Annotated[int, Identity]
name: Annotated[str, MinLen(50), MaxLen(10)] # ERROR: MinLen > MaxLen
temp: Annotated[float, Min(200), Max(125)] # ERROR: Min > Max
secret: Annotated[str, ReadOnly(), WriteOnly()] # ERROR: inaccessible field
verify_raising(Sensor) # VerificationError with all issuesThree built-in phases — numeric constraints, length constraints, semantic flags — each running as a standard compilation phase. Open-world: add your own verification phases without modifying emergent.
# Level 1 — auto CRUD: one decorator, full API
@schema_meta(http_crud("/products", Store))
@dataclass
class Product:
id: Annotated[int, Identity]
name: str
price: float
# Level 2 — CRUD + methods: derive CRUD, hand-write domain logic
@schema_meta(http_crud("/bounties", Board, ops=(LIST, GET, CREATE)), Methods())
@dataclass
class Bounty:
id: Annotated[int, Identity]
title: str
reward: int
@classmethod
@post("/bounties/{bounty_id}/claim")
async def claim(cls, db: ..., bounty_id: int, hunter: str) -> Result[Bounty, DomainError]: ...
# Level 3 — hand-written methods: every endpoint explicit, full control
@schema_meta(Methods())
@dataclass
class Auth:
@classmethod
@post("/login")
async def login(cls, creds: Credentials) -> Result[Token, AuthError]: ...
# Level 4 — raw wire: one endpoint, three targets
endpoint(runner)
.expose(HTTPRouteTrigger("POST", "/register"), rrc(Req, Resp))
.expose(CLITrigger("register"), rrc(Req, Resp))
.expose(TelegrindTrigger(Command("register")), rrc(Req, Resp))Pick what fits. Mix in one app. Drop down a level when you need control, stay high when you don't.
Transforms in emergent dispatch on domain meaning, not syntax. This is a novel mechanism — no existing macro system combines domain-semantic awareness with compositional algebra:
@schema_meta(
http_crud("/posts", Posts),
WithoutDelete(), # ← removes DELETE op across all targets
Paginated(20), # ← adds pagination to ops with Pageable effect
Sorted(), # ← adds sorting to LIST
Filtered("author"), # ← adds exact-match filter
)
@dataclass
class Post:
id: Annotated[int, Identity]
title: str
body: str
author: strCapabilities stack as arguments in @schema_meta() — frozen data in, frozen data out. They compose because they operate on algebraic structure, not string templates or AST nodes.
| Example | What it shows |
|---|---|
roulette/ |
HTTP + CLI + Telegram from one codebase |
cross_compile/ |
Bridge legacy FastAPI → CLI |
full_stack/ |
Full-stack example |
wiring.py |
Raw wire: endpoint + trigger + codec |
A story-driven, 27-chapter walkthrough — from first API to handing your codebase to a coding agent.
Start here → docs/tutorial/00-intro.md
| Part | Chapters | What you'll build |
|---|---|---|
| I–IV | 01–14 | CRUD, methods, transforms, auth, nested resources, multi-target, custom dialects, raw wire, bridge |
| V–VI | 15–18 | Query axis, providers, ops & runners, scope & DI |
| VII–VIII | 19–24 | Enrichers, storage, compilation internals, stateful codecs, roulette walkthrough, design philosophy |
| IX | 25–27 | Verify & explain, why emergent is LLM-native, agent workflows |
docs/intro.md |
Introduction (EN) |
docs/intro_ru.md |
Введение (RU) |
docs/essence.md |
The essence — one function, one operator |
docs/philosophy.md |
Design philosophy |
docs/architecture/ |
Architecture — theory, invariants, algebraic properties |
docs/reference/wire-reference.md |
Wire reference — axes, capabilities, compile, bridge |
docs/reference/cheatsheet.md |
Cheatsheet — all axes, every import, every pattern |
docs/reference/universal-derivation.md |
Derivation — entity → endpoints via fold |
docs/architecture/compiler-deep-dive.md |
Compiler deep-dive — developing custom compilers |
docs/architecture/emergent-and-ai.md |
emergent + AI agents |
emergent is young — started January 2026, three months in. Already runs in production. The core architecture (IR model, compilers, capabilities, verify, explain, derive) is stable. What's still growing: the ecosystem, the stdlib, the number of built-in targets and dialects. Breaking changes happen, but we keep them well-motivated.
| Layer | What |
|---|---|
| deployme.py | Application → infrastructure (compose, k8s) |
| emergent | ops, wire, derive, saga, cache, graph, idempotency, verify |
| nodnod | dependency graphs |
| combinators.py | retry, timeout, fallback |
| kungfu | Result, Option |
Describe. Access. Persist. Expose.
Plain Python. Write meaning, compile anywhere.