Ground-up path
Start small and keep every layer visible.
The basic template is a working SvelteKit app, not an empty folder. It gives you the safe framework setup while leaving product choices open.1. Create and run the app
The template package exports a tested copy helper. Generated projects require Node 24.18 or newer and use the package manager version declared in the template.
terminal
bash
pnpm add -D @happyvertical/smrt-template-sveltekit
node --input-type=module -e "import { copyTemplate } from '@happyvertical/smrt-template-sveltekit'; copyTemplate('./my-app', { name: 'my-app' })"
cd my-app
pnpm install
cp .env.example .env
pnpm db:migrate
pnpm dev2. Read the first object
src/lib/objects/Item.ts shows the main pattern. Its fields become stored data; tenant
scope says whether a row is shared or tenant-owned; the interface options generate the public surfaces.
src/lib/objects/Item.ts
typescript
@smrt({
api: { include: ['list', 'get', 'create', 'update', 'delete'] },
mcp: { include: ['list', 'get', 'create', 'update', 'delete'] },
cli: { include: ['list', 'get', 'create', 'update', 'delete'] }
})
@TenantScoped({ mode: 'optional' })
export class Item extends SmrtObject {
@tenantId({ nullable: true })
tenantId: string | null = null;
title = '';
status = 'draft';
}3. Continue through the foundations
- Objects and collectionsRename Item and add the first useful fields and relationships.
- TenantsDecide whether records are global, tenant-owned, or part of a tenant hierarchy.
- Users and profilesConnect your sign-in provider and keep product identity separate.
- Memberships and permissionsSeed roles and protect app-owned mutations.
- Pages and live dataLoad on the server, then hydrate browser collections only where needed.
- Generated interfacesChoose the REST, MCP, WebMCP, and CLI actions each model should expose.