Getting Started
Install wisp, write your first route, and deploy it to your own AWS account.
Prerequisites
- Bun 1.1 or later.
- An AWS account, with credentials available the way the AWS CLI already expects them — a profile in
~/.aws/credentials, or the usualAWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEYenvironment variables. wisp deploys directly to your own account; there's no separate wisp-hosted control plane to sign up for.
Quick start
The fastest way to a working project — scaffolds wisp.config.ts, a first route, and everything below for you:
bunx create-wisp-app my-app
cd my-app
bun run devPass --region <region> to pick a region up front, or --no-install to skip the automatic bun install. Run
bunx create-wisp-app --help for the full list of options.
Prefer to see exactly what gets created? The rest of this page builds the same project by hand, one file at a time.
Install
npm install @vorynza/wispCreate wisp.config.ts
Every wisp project needs a config file at its root:
export default {
app: "hello-world",
target: "aws",
region: "eu-north-1",
};app— a short name, used to derive every resource's physical name (hello-world-dev-...).target—"aws"is the only implemented target today.region— the AWS region to deploy into.profile— optional; an AWS CLI profile name, if you don't want the default credential chain.
Write your first route
wisp looks for source files under src/. Create src/app.ts:
import { Api } from "@vorynza/wisp";
export const api = new Api("main");Then a route in src/routes/hello.ts:
import { api } from "../app.ts";
export const hello = api.get("/", {}, async () => {
return { status: 200, body: { message: "hello from wisp" } };
});That's it — no router to register, no separate handler file. api.get(path, options, handler) is the
registration; the compiler finds it by reading your source statically, not by executing it.
Synth before you deploy
wisp synth compiles your project to a CloudFormation template without touching AWS — worth running first so you
can see exactly what's about to be created:
wisp synthThis writes .wisp/cloudformation.json and .wisp/graph.json. Open the template if you're curious; it's plain,
readable JSON — one AWS::Lambda::Function, one AWS::IAM::Role scoped to nothing (this handler doesn't touch a
Store, Queue, or Bucket), and the API Gateway wiring.
Deploy
wisp deploywisp bundles your function, uploads it, and deploys the stack via a CloudFormation change set. On success it prints your API's invoke URL:
✓ Stack deployed: CREATE_COMPLETE
MainInvokeUrl: https://abc123.execute-api.eu-north-1.amazonaws.comcurl https://abc123.execute-api.eu-north-1.amazonaws.com/
# {"message":"hello from wisp"}What just happened
One route deployed to exactly one Lambda function, fronted by an HTTP API on API Gateway, with an IAM role that
grants nothing beyond writing its own CloudWatch logs. If you'd referenced a Store or
Queue from inside hello's handler, wisp would have derived exactly the permissions that
handler needs — see IAM derivation for how that works.
Next steps
- Add a
Storeand persist something. - Read Local Development —
wisp devbridges real traffic to your local machine with hot reload, so you're not redeploying on every change. - Skim the CLI reference for every command wisp ships.
- When you're ready to tear it down:
wisp destroy.

