Browse topics
Quick Start
Scaffold an applet, write a typed method, and install it locally with the rprp CLI.
This walks through building a minimal applet: scaffold it, declare a method, implement it, and install it. You need the rprp CLI (ships with RightPlace Core).
1. Scaffold
rprp applet init my-applet --template blank
cd my-applet
Templates are blank, docs-like, and table-like. Each is runnable and lint-clean out of the box. The scaffold gives you applet.json, src/index.ts, src/mount.tsx, and a methods/ folder.
2. Declare the manifest
applet.json declares the id, the scopes the applet uses, the methods it exposes, and which of those are agent tools.
{
"schemaVersion": 2,
"runtime": "sidecar",
"id": "@my-org/notes",
"version": "0.1.0",
"name": "Notes",
"author": "My Org",
"resourceTypes": ["note"],
"scopes": ["projectDb:read", "projectDb:write", "events:emit", "system:sidecar"],
"methods": [
{ "name": "@my-org/notes.add", "permission": "projectDb:write", "handler": "backend" },
{ "name": "@my-org/notes.list", "permission": "projectDb:read", "handler": "backend" }
],
"tools": ["@my-org/notes.add", "@my-org/notes.list"],
"frontend": { "entry": "dist/index.js" }
}
Every id follows @<author>/<slug>. Every method name follows @<author>/<slug>.<verb> - one dot, one camelCase verb. See the Manifest Reference.
3. Write a method
A method is a typed unit declared with defineMethod. Params and returns are Zod schemas, so calls are validated on both sides.
// src/methods/add.ts
import { defineMethod, z } from "@rightplace/applet-sdk/v2";
import { Note } from "../entities.js";
export const add = defineMethod({
name: "@my-org/notes.add",
scope: "resource",
runIn: "backend",
permission: "projectDb:write",
params: z.object({ title: z.string(), body: z.string() }),
returns: Note.schema,
async run({ title, body }, ctx) {
const note = await Note.insert({
id: ctx.uuid(),
title,
body,
createdAt: ctx.now(),
});
await ctx.events.emit("@my-org/notes.added", { note });
return note;
},
});
Define the entity it stores into:
// src/entities.ts
import { defineEntity, z } from "@rightplace/applet-sdk/v2";
export const Note = defineEntity({
name: "note",
storage: "sqlite",
schema: z.object({
id: z.string().uuid(),
title: z.string(),
body: z.string(),
createdAt: z.number().int(),
}),
primaryKey: "id",
});
4. Call it
From the frontend, methods are called by their full name:
const note = await ctx.methods["@my-org/notes.add"]({
title: "First note",
body: "Hello",
});
From the CLI:
rprp call '@my-org/notes.add' --args '{"title":"First note","body":"Hello"}'
5. Package and install
rprp applet package --sign <keypath>
rprp applet install # scans ./dist/*.rpbundle.zip and installs
During development, rprp applet dev watches your source, rebuilds, and reinstalls on save.
Next
- Method Architecture - how a method routes through its layers
- Entities & Storage - querying, indexes, subscriptions
- Agent Tools - make methods callable by agents
- Permissions & Scopes - what each scope grants