AppTheory is a TableTheory-style multi-language monorepo for building serverless applications with a shared runtime contract and cross-language drift prevention.
Distribution: GitHub Releases only (no npm/PyPI publishing).
AppTheory exists to provide a portable runtime core (and contract tests) for AWS serverless applications that must be first-class in Go, TypeScript, and Python.
Target audiences and use cases:
- Platform and application teams building HTTP APIs on AWS Lambda (Lambda Function URL, API Gateway v2).
- Event-driven workloads (SQS, EventBridge, DynamoDB Streams) and WebSockets are required for Lift parity and are tracked
as remaining contract work (see
docs/development/planning/apptheory/apptheory-gap-analysis-lesser.md). - Internal tooling and shared libraries that need consistent request/response semantics across languages.
Non-goals (near-term):
- Not a general-purpose web framework; contract-first serverless runtime only.
- Not registry-published packages (no npm or PyPI); releases ship via GitHub assets.
- Go module path:
github.com/theory-cloud/apptheory - Go runtime package:
github.com/theory-cloud/apptheory/runtime - npm package:
@theory-cloud/apptheory - Python distribution name:
apptheory - Python import name:
apptheory
- Go toolchain:
1.26.1 - Node.js:
24 - Python:
3.14
- Main docs index:
docs/README.md - TypeScript package docs:
ts/docs/README.md - Python package docs:
py/docs/README.md - CDK package docs:
cdk/docs/README.md
- P0: routing + request/response normalization + error envelope
- P1: request-id, tenant extraction, auth hooks, CORS, size/time guardrails, middleware ordering
- P2 (default): P1 + observability hooks + rate limiting / load shedding policy hooks
- CSRF protection and secure cookie flags are application concerns; set
Secure/HttpOnly/SameSiteexplicitly inSet-Cookie. - Request IDs can be supplied via
x-request-id; validate/override if your threat model requires it. - Retries/backoff for event sources are handled by AWS trigger settings (retry policies, DLQs/redrive), not by the runtime.
The Go runtime implements the fixture-backed contract across P0/P1/P2 tiers (default: P2).
Notes:
- Header names are case-insensitive, but
Request.Headers/Response.Headerskeys are canonicalized to lowercase. - If two routes are equally specific, the router prefers earlier registration order.
Minimal local invocation:
env := testkit.New()
app := env.App()
app.Get("/ping", func(ctx *apptheory.Context) (*apptheory.Response, error) {
return apptheory.Text(200, "pong"), nil
})
resp := env.Invoke(context.Background(), app, apptheory.Request{Method: "GET", Path: "/ping"})
_ = respTo force the P0 core (minimal surface area), pass apptheory.WithTier(apptheory.TierP0) when creating the app.
Unit test without AWS (deterministic time + IDs + HTTP event builder):
func TestHello(t *testing.T) {
env := testkit.NewWithTime(time.Date(2026, 1, 1, 0, 0, 0, 0, time.UTC))
env.IDs.Queue("req-1")
app := env.App()
app.Get("/hello", func(ctx *apptheory.Context) (*apptheory.Response, error) {
return apptheory.MustJSON(200, map[string]any{
"now_unix": ctx.Now().Unix(),
"id": ctx.NewID(),
}), nil
})
event := testkit.APIGatewayV2Request("GET", "/hello", testkit.HTTPEventOptions{
Headers: map[string]string{"x-request-id": "request-1"},
})
resp := env.InvokeAPIGatewayV2(context.Background(), app, event)
if resp.StatusCode != 200 {
t.Fatalf("expected status 200, got %d", resp.StatusCode)
}
if resp.Headers["x-request-id"] != "request-1" {
t.Fatalf("expected x-request-id request-1, got %#v", resp.Headers["x-request-id"])
}
var body map[string]any
if err := json.Unmarshal([]byte(resp.Body), &body); err != nil {
t.Fatalf("parse response json: %v", err)
}
if body["id"] != "req-1" {
t.Fatalf("expected id req-1, got %#v", body["id"])
}
}Start here:
- Planning index:
docs/development/planning/apptheory/README.md - Main roadmap:
docs/development/planning/apptheory/apptheory-multilang-roadmap.md - Import pipeline support pack reference example (CDK + handlers):
examples/cdk/import-pipeline/
Migration:
- Lift → AppTheory (draft):
docs/migration/from-lift.md
License:
- Apache 2.0 (see
LICENSE)