Supercharge existing syntax with Capy¶
You don't have to invent a brand-new language to use Capy. The most practical pattern is to take an existing target format (SQL, Markdown, HTML, Dockerfile, Kubernetes manifests, Terraform HCL, GitHub Actions, .env files, anything textual) and put a Capy layer on top of it.
The output is still plain SQL, plain Markdown, plain whatever. Your existing toolchain — databases, static-site generators, CI runners, package managers — keeps working unchanged.
What Capy adds is the authoring surface: macros, components, typed inputs, conditional generation, and a library that doubles as a spec.
The mental model¶
Author ───► script.capy ───► capy run ───► target.{sql,md,yaml,...}
(humans (library does
or AI) the heavy lifting) │
▼
Existing tool
(psql, hugo,
kubectl, …)
You're inserting Capy as a preprocessor before the existing tool. Nothing downstream knows Capy exists.
Why this beats writing the host format by hand¶
For every host format, the same three things go wrong:
- Boilerplate is repetitive and error-prone. Every Postgres
table needs the same
created_at/updated_atcolumns. Every Kubernetes deployment needsapiVersion,kind,metadata,spec— and the indentation is unforgiving. - No type checking at the input boundary. Misspell an enum
value in YAML, the kubelet rejects it 30 seconds later. Misspell
a
tagin Markdown frontmatter, the static site silently renders an empty tag page. - No composition. Want every table to have an audit-columns macro? In raw SQL you copy-paste. In Capy you write one library function and it's available everywhere.
Capy fixes all three:
- The library defines the boilerplate once. Authors write the intent.
arg capture x SomeTypeplustype SomeType { pattern: ... }means typos become transpile-time errors.- Functions in a library are reusable across every source file that uses that library.
Worked sample — SQL DDL with macros¶
Source (32 lines):
table users
pk id
col email "varchar(255) UNIQUE NOT NULL"
col name "varchar(100)"
timestamps
end
table posts
pk id
fk author_id -> users
col title "varchar(255) NOT NULL"
col body "text"
timestamps
soft_delete
end
index posts author_id
Output (clean Postgres DDL, no Capy dependency at runtime):
CREATE TABLE users (
id bigserial PRIMARY KEY,
email varchar(255) UNIQUE NOT NULL,
name varchar(100),
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now()
);
-- ... etc
The DSL macros (pk, fk, timestamps, soft_delete, index)
each expand to 1-3 lines of SQL. Multiply across a 20-table schema
and you've removed every audit-column typo from the codebase.
Worked sample — Markdown blog with components¶
Source (26 lines):
post "Adopting Capy at Acme" date "2026-05-24" author "Alice Chen"
tag rust
tag devtools
para "We replaced 3 hand-rolled generators with one Capy library."
h2 "Why Capy"
bullet "Single source — multiple targets."
bullet "Library doubles as the spec."
callout note "This post is itself generated by Capy."
card "Generators retired" "3" "all replaced by 1 library"
end
Output: real Markdown with YAML frontmatter, blockquote callouts, and inline HTML metric cards. Drop it into Hugo, Jekyll, MkDocs, Next.js, Astro — they all render it.
Recipe — picking the host format¶
Most useful candidates for "supercharging":
| Host format | What Capy adds |
|---|---|
| SQL DDL | pk / fk / timestamps / soft_delete / audit_columns |
| Markdown | Frontmatter, callouts, cards, code-with-output |
| HTML | Component primitives that expand to plain HTML+CSS+JS |
| Dockerfile | base / apt / pip / multi-stage builds in one line |
| GitHub Actions | job / steps shorthand expanding to full workflow YAML |
| Terraform HCL | Module shortcuts, env-aware defaults |
| Kubernetes | One-liner deployments expanding to full manifests |
| OpenAPI | Endpoint-shorthand expanding to full operationId + schema |
| Mermaid | High-level diagram shorthand expanding to node + edge DSL |
For each one, the recipe is identical:
- Set
extension: <target ext>in the library. - Define functions for the high-level statements you want authors to use.
- Make
file_templateemit the host format that wraps everything. - (Optional) Add
typeblocks withpattern:/options:to validate authored values.
The library is typically 30-100 lines and replaces several hundred lines of hand-written boilerplate in the source repo.
What it isn't¶
- Not a template engine. Capy parses + validates input, then emits output. Templates (Jinja, Handlebars) take a prebuilt data structure and stringify it — they have no notion of grammar.
- Not a transpiler-to-runtime. The host format is plain text; the database / browser / CI / kubectl runs it. Capy doesn't execute anything at runtime.
- Not a replacement for the host format. You still need to know Postgres / Markdown / Kubernetes — Capy just gives you a nicer authoring surface for it.
The pattern is: write the boilerplate once in the library; let authors compose at the high level.