Quickstart

This takes you from an empty folder to a live HTTPS endpoint in your own AWS account, plus a scheduled job and a queue consumer, in a few minutes. You need Node.js 22, a laranja API key, and AWS credentials on your machine.

1. Create a project

mkdir my-api && cd my-api
npm init -y
npm install express
npm install -D @alzulejos/laranja typescript
npm install @alzulejos/laranja-decorators

laranja supports Express and NestJS. For Nest, see the HTTP apps guide.

2. Write your app

Mark your app with http() and export it. laranja finds it by reading your code — so there's nothing to wire up in config:

// src/app.ts
import express from "express";
import { http } from "@alzulejos/laranja-decorators";

const app = express();
app.get("/", (_req, res) => res.json({ ok: true, stage: process.env.STAGE }));
app.get("/users/:id", (req, res) => res.json({ id: req.params.id }));

export default http(app);

Add a scheduled job and a queue consumer (optional). There are two styles — pick whichever fits your codebase.

// src/jobs.ts
import { cron, queue, rate } from "@alzulejos/laranja-decorators";

export async function refreshCache() {
  console.log("refreshing cache…");
}
cron(rate(5, "minutes"), refreshCache);

export async function sendEmail(body: unknown) {
  console.log("sending", body);
}
queue({ name: "emails", batchSize: 10 }, sendEmail);

3. Sign in and configure

Run the scaffolder. It prompts for your laranja API key (from the dashboard), validates it, stores it in ~/.laranja/auth.json, and lets you pick or create a dashboard project — filling in name and projectId for you:

npx laranja init

The generated laranja.config.ts looks like this (edit region, env, and compute to taste):

// laranja.config.ts
import type { LaranjaConfig } from "@alzulejos/laranja-decorators";

const config: LaranjaConfig = {
  name: "my-api",
  // From your laranja dashboard — identifies this project on the server.
  projectId: "proj_…",
  region: "us-east-1",
  env: { LOG_LEVEL: "info" },
  // Default compute for every function (the HTTP proxy + each cron/queue).
  compute: { memory: 256, timeout: 30 },
};

export default config;

Because the app is marked with http() in code, the config stays minimal — the HTTP app is declared there, not in config. See the config reference.

Deploying to Azure instead? Everything below is identical — add provider: "azure" and an azure block (or pick Azure when init prompts) and follow Deploying to Azure. The rest of this page shows AWS output.

4. Preview the plan

plan shows what a deploy would do: it synthesizes your template on the server, diffs it against what's deployed in your account, and tags each resource created / changed / unchanged. It's read-only — nothing is applied, and it never counts against your deploy limit.

npx laranja plan
Plan for "my-api-dev"

+ http     HTTP   2 routes → proxy Lambda + Function URL
+ daily    Cron   Lambda + EventBridge rule
+ emails   Queue  SQS + consumer Lambda

8 AWS resources  +8 created  =0 unchanged

On this first run nothing is deployed yet, so everything shows as + created.

5. Deploy

npx laranja deploy

On AWS, the first deploy to a new account/region prompts you to bootstrap (a one-time setup in your account). When it finishes you'll see your live URL:

🌐 http   https://abc123.lambda-url.us-east-1.on.aws/

Hit it:

curl https://abc123.lambda-url.us-east-1.on.aws/
# {"ok":true,"stage":"dev"}

6. Iterate

npx laranja logs            # tail your functions' logs (pick a function)
npx laranja plan            # see what a deploy would change
npx laranja deploy          # ship again
npx laranja destroy         # tear it all down

Next steps