Skip to content

PROJECT SCAFFOLDING

One source → an entire project tree

A single .capy source file can scaffold a complete project — web app, Android app, iOS app, ML training code, full Python service. Same engine, vastly different artifacts. Add --zip to bundle the tree into a single archive.

12 lines
to scaffold a 3-file web app
15 lines
to scaffold a 7-file Android app
17 lines
to scaffold a libtorch C++ ML trainer
go test ✓
on auto-generated backend tests

📱 Mobile — same source, two platforms

The same source declaration produces a working Android skeleton and an iOS SwiftUI skeleton. Each library encodes its platform's conventions (Kotlin/SwiftUI idioms, manifest formats, build configs); the source stays platform-agnostic.

The whole declaration:

app "Habit Tracker"
    package "com.example.habits"
    min_sdk 24

    screen Home    "Today's habits"
    screen History "Past 30 days"

    feature Home    "Daily checklist"
    feature Home    "Streak counter"
    feature Home    "Reset day"
    feature History "Calendar view"
    feature History "Per-habit stats"
end

The Android library encodes Kotlin source layout, AndroidManifest.xml, gradle build, fragment scaffolding. The iOS library encodes SwiftUI App/View structure, Info.plist, SPM manifest.

Add a screen line, regenerate, both platforms update.

See the Android sample → iOS sample →

The phone above runs the same idea as a single-page web app (generated by samples/webapp-trio/) so you can interact with it. The Android + iOS samples generate native code with the same screens and features.


🌐 Web app — 12 lines of DSL → 3-file browser-ready app

app "Habit Tracker"
    description "A tiny daily-habit tracker that persists to localStorage."
    color_primary "#4f46e5"
    color_bg "#0f172a"

    habit drink_water  "Drink 8 glasses of water"
    habit read         "Read 20 pages"
    habit walk         "30 min walk"
    habit code         "Practice coding"
    habit meditate     "Meditate 10 min"
end

Three files, properly cross-referenced:

📁 out/
index.html // links to styles.css + app.js
app.js // localStorage persistence + streak counter
styles.css // themed by source variables

  • localStorage persistence baked in by the library
  • Streak counter computed across consecutive days
  • Theme variables pulled from color_primary / color_bg
  • Cross-references wired correctly — the <link> and <script src> point at sibling files
capy run --out-dir out lib.capy script.capy
open out/index.html
file:///out/index.html

🧪 Backend — handler + test code from one declaration

Every handler line generates two things: the Go stub and the smoke test. The team's directory layout and the "every handler has a test" rule are mechanically enforced.

Source:

handler ListUsers   method GET     path "/users"        returns "[]User"
handler GetUser     method GET     path "/users/{id}"   returns "User"
handler CreateUser  method POST    path "/users"        accepts "UserCreateRequest"  returns "User"
handler DeleteUser  method DELETE  path "/users/{id}"   returns "void"

Generated tree:

📁 internal/handlers/
handlers.go // router + 4 stubs (501)
handlers_test.go // 4 Test_X_RouteRegistered

README.md // auto-generated route catalog

See the backend sample →

~/handlers — zsh
$ go test ./...
ok    example/handlers   0.448s

$ go test -v ./...
=== RUN   Test_ListUsers_RouteRegistered
--- PASS: Test_ListUsers_RouteRegistered (0.00s)
=== RUN   Test_GetUser_RouteRegistered
--- PASS: Test_GetUser_RouteRegistered (0.00s)
=== RUN   Test_CreateUser_RouteRegistered
--- PASS: Test_CreateUser_RouteRegistered (0.00s)
=== RUN   Test_DeleteUser_RouteRegistered
--- PASS: Test_DeleteUser_RouteRegistered (0.00s)
PASS
ok    example/handlers   0.448s

The generated tests actually pass. Verified.


🧠 ML training — declarative architecture → native libtorch C++

model "MNIST classifier"
    dataset MNIST
    batch_size 64
    epochs 10
    learning_rate 0.001
    optimizer adam

    layer conv2d   in 1   out 32   kernel 3
    layer relu
    layer maxpool  kernel 2
    layer conv2d   in 32  out 64   kernel 3
    layer relu
    layer maxpool  kernel 2
    layer flatten
    layer linear   in 1600 out 128
    layer relu
    layer linear   in 128  out 10
end

17 lines → native code that compiles to a CUDA-enabled trainer.

📁 out/
CMakeLists.txt // finds libtorch, links targets
run.sh // configure + build + run
src/
   ├ model.h // torch::nn::Module with register_module + forward
   └ main.cpp // training loop with optimizer + checkpoints

The same architecture declaration could target PyTorch Python, Keras, ONNX, or TFLite — write a new library, keep the source.

See the libtorch sample →


🐍 Multi-file Python service — 9 lines, 6 files

A REST API declaration produces a complete FastAPI project:

project "todo-api"
    description "A tiny TODO REST service"
    author "you@example.com"

    route GET    "/health"     health_check
    route GET    "/todos"      list_todos
    route POST   "/todos"      create_todo
    route GET    "/todos/{id}" get_todo
    route DELETE "/todos/{id}" delete_todo
end

📁 generated/
README.md
pyproject.toml // fastapi + uvicorn deps
.gitignore
src/
   ├ main.py // FastAPI app with 5 routes mounted
   └ handlers.py // handler stubs ready to implement
tests/
   └ test_smoke.py // route-mount tests

Full sample →


How it works

# Write the source to a tree of file blocks declared in the library
capy run --out-dir generated  lib.capy script.capy

# OR bundle the whole tree as a zip for delivery
capy run --zip   project.zip   lib.capy script.capy

The library has one file "..." ... end block per output file. File paths support the same ${...} interpolation as write literals — so you can name outputs dynamically (file "${name | pascalCase | unquote}Page.tsx" ... end).

Multi-file file block reference →