wispwisp

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 usual AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY environment 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 dev

Pass --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/wisp

Create wisp.config.ts

Every wisp project needs a config file at its root:

wisp.config.ts
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:

src/app.ts
import { Api } from "@vorynza/wisp";

export const api = new Api("main");

Then a route in src/routes/hello.ts:

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 synth

This 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 deploy

wisp 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.com
curl 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 Store and persist something.
  • Read Local Developmentwisp dev bridges 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.

On this page