Getting Started

Project structure

What lives in your Vadyl project — entities, handlers, workflows, agents, connections, edge — and how Vadyl discovers it all.

Vadyl projects follow a convention-based layout. There's no framework boilerplate — every directory holds one kind of canonical product backend asset, and Vadyl discovers them automatically from the source tree at build time.

The layout

my-app/
├── vadyl.config.ts        # bindings, deployments, environments
├── schema/                # canonical entities
│   ├── User.vadyl.ts
│   ├── Order.vadyl.ts
│   └── Product.vadyl.ts
├── src/
│   ├── handlers/          # request-time handlers
│   ├── workflows/         # durable orchestration
│   ├── events/            # event consumers
│   ├── scheduled/         # cron / interval / once jobs
│   ├── webhooks/          # inbound webhook handlers
│   ├── edge/              # edge runtime handlers
│   ├── management/        # admin / lifecycle handlers
│   ├── agents/            # AI agent definitions
│   ├── connections/       # governed connection bindings
│   └── policies/          # access policies (optional, can also be inline)
└── tests/

schema/ — canonical entities

Every *.vadyl.ts file in schema/ exports one or more entity contracts. These are the canonical truth about your product's data shape, relationships, validation, and access. Vadyl compiles them into the right DDL for whichever database you bound, plus typed clients, REST routes, GraphQL types, and gRPC contracts.

src/handlers/ — request-time handlers

Core request handlers — synchronous logic invoked through the API surface. Each file maps to one operation. Handlers reach data through the runtime bridge (ctx.entities.*) — never raw SQL.

// src/handlers/orders/calculateRefund.ts
import { handler } from "@vadyl/sdk";


export default handler.core(async (ctx, input: { orderId: string }) => {
  const order = await ctx.entities.Order.read(input.orderId);
  return { refundable: order.status === "paid" ? order.total : 0 };
});

src/workflows/ — durable orchestration

Long-running, journaled, replayable. Workflows survive process restarts because every step is durable. Use them when a single request spans multiple external calls, waits, or compensations.

src/events/ — event consumers

Subscribe to canonical entity events (order.created,user.updated) or custom platform events. Consumers are idempotent under at-least-once delivery — Vadyl guarantees it.

src/scheduled/ — cron / interval / once

Scheduled handlers fire on cron expressions, intervals, or once at a given time. Each run is durable, retryable, and observable through the same lifecycle as authored handlers.

src/webhooks/ — inbound webhook handlers

Receive signed webhooks from third parties. Vadyl handles signature verification, idempotency receipts, and retries.

src/edge/ — edge runtime handlers

Constrained handlers that run at the CDN edge. Use them for request shaping, geo routing, rate-limit prechecks, session prechecks. Edge handlers cannot read or write entities — see Authored runtime.

src/management/ — admin / lifecycle handlers

Privileged handlers that perform schema transitions, branching operations, runtime publication mutations, deployment operations, or installable surface publishing. They're gated by management authority — ordinary request handlers cannot invoke them.

src/agents/ — AI agent definitions

Native agent definitions with model bindings, plan IR, memory scope, and skill definitions. See Agents.

src/connections/ — governed connection bindings

Typed configuration for outbound integrations: HTTP APIs, OAuth, SMTP, SMS, payment, LLM, broker, search, KMS. Each connection carries secret references via the keyring, capability descriptors, egress policy, and observability hooks.

vadyl.config.ts

export default {
  project: { id: "my-app", region: "us-east-1" },
  bindings: {
    primary:  { type: "postgres" },
    cache:    { type: "redis" },
    storage:  { type: "s3" },
  },
  environments: ["dev", "staging", "production"],
};

That's the entire conventions surface. Everything else lives where it belongs.