Skip to content

YAML & Project Structure

Project layout, YAML definition files, and naming conventions.

myapp/
├── .wippy.yaml # Runtime configuration
├── wippy.lock # Source directories config
├── .wippy/ # Installed modules
└── src/ # Application source
├── _index.yaml # Entry definitions
├── api/
│ ├── _index.yaml
│ └── *.lua
└── workers/
├── _index.yaml
└── *.lua
YAML definitions are loaded into the registry at startup. The registry is the source of truth - YAML files are one way to populate it. Entries can also come from other sources or be created programmatically.

Any YAML file with a namespace plus either an entries array or a top-level name+kind is a valid definition file. version is optional:

version: "1.0"
namespace: app.api
entries:
- name: get_user
kind: function.lua
meta:
comment: Fetches user by ID
source: file://get_user.lua
method: handler
modules:
- sql
- json
- name: get_user.endpoint
kind: http.endpoint
meta:
comment: User API endpoint
method: GET
path: /users/{id}
func: get_user
FieldRequiredDescription
versionnoSchema version (currently "1.0")
namespaceyesEntry namespace for this file
entriesyesArray of entry definitions

Use dots (.) for semantic separation and underscores (_) for words:

# Function and its endpoint
- name: get_user # The function
- name: get_user.endpoint # Its HTTP endpoint
# Multiple endpoints for same function
- name: list_orders
- name: list_orders.endpoint.get
- name: list_orders.endpoint.post
# Routers
- name: api.public # Public API router
- name: api.admin # Admin API router
Pattern: base_name.variant - dots separate semantic parts, underscores separate words within a part.

Namespaces are dot-separated identifiers:

app
app.api
app.api.v2
app.workers

Entry full ID combines namespace and name: app.api:get_user

The wippy.lock file defines where Wippy loads definitions from:

directories:
modules: .wippy
src: ./src

Wippy recursively scans these directories for YAML files.

Each entry in the entries array. Properties are at root level (no data: wrapper):

entries:
- name: hello
kind: function.lua
meta:
comment: Returns hello world
source: file://hello.lua
method: handler
modules:
- http
- json
- name: hello.endpoint
kind: http.endpoint
meta:
comment: Hello endpoint
method: GET
path: /hello
func: hello

Use meta for UI-friendly information:

- name: payment_handler
kind: function.lua
meta:
title: Payment Processor
comment: Handles Stripe payments
source: file://payment.lua

Convention: meta.title and meta.comment render nicely in management UIs.

Use registry.entry kind for application-level configuration:

- name: config
kind: registry.entry
meta:
title: Application Settings
type: application
environment: production
features:
dark_mode: true
beta_access: false
KindPurpose
registry.entryGeneral-purpose data
function.luaCallable Lua function
process.luaLong-running process
http.serviceHTTP server
http.routerRoute group
http.endpointHTTP handler
process.hostProcess supervisor

See Entry Kinds Guide for complete reference.

Runtime configuration at project root:

version: "1.0"
logger:
encoding: json
logmanager:
min_level: 0
supervisor:
host:
worker_count: 16

See Configuration Guide for all options.

Defines source directories:

directories:
modules: .wippy
src: ./src

Reference entries by full ID or relative name. Children attach to their parent through meta, not via parent-side lists:

# Router declares itself against a server
- name: api
kind: http.router
meta:
server: app:gateway
prefix: /api
# Endpoint references router by registry ID (cross-namespace works the same way)
- name: get_user.endpoint
kind: http.endpoint
meta:
router: app.api:api
method: GET
path: /users/{id}
func: app.api:get_user
myapp/
├── .wippy.yaml
├── wippy.lock
└── src/
├── _index.yaml # namespace: app
├── api/
│ ├── _index.yaml # namespace: app.api
│ ├── users.lua
│ └── orders.lua
├── lib/
│ ├── _index.yaml # namespace: app.lib
│ └── database.lua
└── workers/
├── _index.yaml # namespace: app.workers
└── email_sender.lua