Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

52 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Wave

A declarative HTTP server framework — describe your backend in capy, ship a single binary.

CI Release License Go

DocsQuickstartCookbookFor AI agents


A working JSON API in 18 lines of capy

storage app
    kind     sqlite
    location "./data.db"

route "/users"
    methods POST
    request
        content_type "application/json"
        body_field name
            type       text
            required   true
            min_length 1
    do
        created = on app do sql `INSERT INTO users (name) VALUES ({{request.name}})`
        match created
            case success(info)
                response
                    status       201
                    content_type "application/json"
                    body         `{"id":{{info.last_insert_id}}}`
wave serve server.capy --listen :8080
curl -X POST -d '{"name":"ada"}' http://localhost:8080/users
# {"id": 1}

That's a working endpoint with input validation, parameterised SQL (the {{request.name}} becomes a bound ? — injection is impossible by construction), a JSON response, and a built-in /healthz probe. No Go code, no node_modules, no Docker Compose stack. Read it top to bottom: what it takes → what it does → what it returns. The same server.capy deploys as a single binary or a 25 MB distroless container.

What ships in the box

→ Full feature inventory — every declaration, route shape, operation, response form, CLI subcommand, plugin kind, in one searchable page.

What
One DSL route + request + do; operations on TARGET do sql|call_plugin|broadcast; match outcomes; response; every schedules; background tasks
Demo apps Self-contained server.capy files under examples/apps/ — chat, polls, todo, pastebin, multi-tenant SaaS, Stripe receiver, SSE chat, photo gallery, OAuth, magic-link, audit-logged admin, ML sidekick, …
Cookbook recipes 30+ copy-paste patterns for the common needs
CLI commands serve, check, describe, docs, export, fmt, lsp, new, migrate, secrets, routes, test, version
Auth schemes session cookie, magic link (email), OAuth (Google/GitHub/Apple/OIDC), API-key header lookup, JWT
Webhook handling Stripe, GitHub, Slack, generic HMAC — all with signature verification + replay protection
Observability Prometheus /metrics, OpenTelemetry traces, JSON access logs, append-only audit log
Reliability durable outbox, circuit breaker, rate limiter, body-size limits, response cache
Tooling wave describe (project manifest → JSON/MD/OpenAPI), wave export (typed clients, mock server), wave lsp (editor language server)
Deploy targets macOS / Linux / Windows binaries + distroless Docker image

Why Wave?

🚀 Ship faster

Most backends are 80% boilerplate — request parsing, validation, DB calls, auth wiring, middleware ordering. Wave does that 80% declaratively. You write Go (or any language, as a plugin) only where it actually matters.

🤖 5-10× fewer tokens for AI-assisted development

The same JSON API endpoint:

Stack Lines Tokens
Wave 18 ~160
FastAPI + Pydantic 24 ~360
Gin (Go) 38 ~440
Express + Zod + Prisma 38 ~520

More features per Cursor request, more state per Claude context window, fewer hallucinations. Wave ships llms.txt, a Claude Code skill, and a self-describing grammar (wave docs --format json) so AI editors auto-complete and produce working configs first try. See the full comparison.

🔒 Safe by construction — not as an afterthought

  • SQL injection: impossible. Inside sql, every {{request.x}} compiles to a bound ? parameter — values never reach the SQL text. It's a property of the compiler, not a rule you must remember.
  • XSS: closed at the template boundary. Response bodies auto-escape for their declared content_type — HTML responses HTML-escape, JSON responses JSON-escape.
  • CSRF, webhook signatures (Stripe / GitHub / Slack), rate limits, circuit breakers, body-size limits, input validation, secure headers — all wired into the request pipeline.
  • RBAC via auth.user.roles, audit log for every mutation.

📦 Real production primitives

  • /healthz + /readyz built in
  • Prometheus /metrics + OpenTelemetry traces
  • Durable outbox for webhook delivery with retry + DLQ
  • Migrations (wave migrate server.capy up)
  • Config check (wave check server.capy --format json) for pre-flight
  • Functional test runner (wave test) — capy-driven, in-process, no port

🧪 Testable end-to-end

# server.test.capy
import "server.capy"

test "create user"
    request POST "/users"
        json { "name": "ada" }
    expect
        status 201
        json   { "id": "*" }
    capture id from json.id

test "read it back"
    request GET "/users/{{id}}"
    expect
        status 200
        json   { "name": "ada" }
wave test server.test.capy --format json    # CI-friendly, in-process, no port binding

Full testing recipe →

🧩 Fits your existing stack

Wave isn't a replacement for React, Node, or Python. It's a complement:

🛠️ Generate clients & docs from the source

wave describe server.capy               # API reference for your app (Markdown / JSON / OpenAPI)
wave export   server.capy --client ts   # a typed TypeScript client for your frontend
wave serve    server.capy --mock        # a mock server for frontend dev (no side effects)

The client a consumer imports is, by construction, the contract the server enforces — both come from the same parse.

Popular integrations — copy-paste recipes

The most-asked "how do I plug Wave into X?" recipes:

Same on PLUGIN do call_plugin / signature-verification / storage primitives — once you've done one, the rest are copy-paste.

Don't see what you need? Build a plugin (any language) — same echo plugin in Go, Python, Node, Rust, and 9-line Bash.

Pick your path

You are… Start here
Trying it for the first time Quickstart (5 min)
Building a real app Tutorial: build a todo API (30 min)
An indie hacker wave new api — scaffolded project with auth + Docker + Fly.io ready
A backend engineer Comparison vs Express / FastAPI / Gin
A platform / SRE engineer Production checklist + Observability
An AI agent builder Token efficiency + Claude skill
Adding Wave to an existing app Wave in your stack

Install

# Pre-built binaries (macOS / Linux / Windows)
curl -sSfL https://olivierdevelops.github.io/wave/install.sh | sh

# Pin a version
curl -sSfL https://olivierdevelops.github.io/wave/install.sh | sh -s -- v0.1.0

# Or via Go (latest main, includes built-in SQLite)
go install github.com/olivierdevelops/wave/orchestrator@latest

# Or via Docker (sqlite-capable)
docker run --rm -p 8080:8080 \
  -v $(pwd)/server.capy:/server.capy \
  ghcr.io/olivierdevelops/wave:latest serve /server.capy --listen :8080

Released binaries are built nosqlite for cross-platform simplicity. Use the Docker image or go install for built-in SQLite. Homebrew formula lands shortly.

CLI at a glance

wave serve    server.capy --listen :8080   # run a server
wave check    server.capy                  # parse + validate (no server)
wave test     server.test.capy             # run a capy test suite
wave describe server.capy --format json    # document what this project does
wave docs     --format json                # document the language itself
wave export   server.capy --client ts      # generate a typed client
wave fmt      server.capy --check          # CI-safe formatter
wave routes   server.capy --format json    # print the route table
wave new      api ./my-project             # scaffold a starter
wave migrate  server.capy up               # apply migrations
wave lsp                                   # editor language server (stdio)

The 30-second taste

git clone https://github.com/olivierdevelops/wave.git
cd wave

# Pick any demo
go run ./orchestrator serve examples/apps/url-shortener/server.capy --listen :8102
curl http://localhost:8102/healthz
# ok

# Or run its test suite
go run ./orchestrator test examples/apps/url-shortener/server.test.capy
#   PASS  built-in /healthz returns ok (200, 1ms)
#   PASS  unknown path returns framework 404 envelope (404, 0s)
#   PASS  POST /shorten validates target pattern (400, 0s)
#
#   8 passed, 0 failed, 0.00s

What it's not

  • Not a frontend framework (it serves your React/Vue/Svelte build, but doesn't render it).
  • Not a service mesh (it sits at L7, in your app; pair with Istio/Linkerd if you need mTLS).
  • Not a workflow engine (it has a scheduler; use Temporal/Airflow if you need durable multi-step workflows).
  • Not a replacement for your domain code — it's the boring parts done declaratively so you can focus on the parts that aren't.

Documentation

Community

  • GitHub Discussions — questions, ideas, show & tell
  • Issues — bug reports and feature requests
  • Discord — coming soon

Status

Pre-1.0. Breaking changes are allowed between 0.x minors and are documented in CHANGELOG.md. Production usage is welcome — pin a version and read the CHANGELOG before upgrading.

Privacy

Wave never phones home. No telemetry, no analytics, no remote config fetches. The single binary only contacts services you configure.

Contributing

PRs welcome. Start with CONTRIBUTING.md for the process and CLAUDE.md for the architecture. Good first issues: good-first-issue.

License

Apache-2.0 — see LICENSE.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages