Code generation

Studio generates plain SvelteKit code you own - there is no runtime and no lock-in. The same scaffold() core powers the CLI, the AI generator, and the visual designer, so all three emit identical files.

The generated files: schema module, +server.ts API route, and +page.svelte screen, with svgrid:managed markers.

What gets generated

From one EntitySchema, three files:

File Contents
src/lib/<name>.schema.ts The EntitySchema literal + a typed row type.
src/routes/api/<name>/+server.ts The API route - createKitHandlers over a data source.
src/routes/<name>/+page.svelte The screen - grid + edit panel, wired to the route.

The generated page is a full data screen: server-side sort, filter, and global search; a native pagination footer; a validated create / edit modal; multi-select optimistic delete; and loading / error / empty states. Any relation (foreign-key) field also gets a searchable lookup wired to the related entity's API route (Relations).

The three files, up close

1. The schema is the single source of truth - a plain literal you can edit by hand or regenerate:

// src/lib/customers.schema.ts
import type { EntitySchema } from '@svgrid/enterprise'

export type CustomersRow = {
  id: string; name: string; email: string; mrr: number; active: boolean
}

export const customersSchema: EntitySchema<CustomersRow> = {
  name: 'customers',
  idField: 'id',
  fields: [
    { field: 'id', type: 'text', primaryKey: true, readonly: true },
    { field: 'name', type: 'text', required: true },
    { field: 'email', type: 'text', format: 'email', required: true },
    { field: 'mrr', type: 'number', min: 0 },
    { field: 'active', type: 'boolean' },
  ],
}

2. The API route is a single POST endpoint. createKitHandlers speaks one JSON wire protocol for read + create + update + delete, so the client needs just the one handler:

// src/routes/api/customers/+server.ts
import { createInMemoryDataSource, createKitHandlers } from '@svgrid/enterprise'
import { customersSchema, type CustomersRow } from '$lib/customers.schema'

const source = createInMemoryDataSource<CustomersRow>([], customersSchema)

export const { POST } = createKitHandlers({ schema: customersSchema, source })

Swap createInMemoryDataSource for a SQL, Supabase, or REST source and the page does not change - that is the ServerDataSource contract at work.

3. The screen wires the grid and the edit panel to that route through the controller - server-side sort / filter / page, the create-edit modal, and optimistic delete. It is a normal +page.svelte you own; see the Data-app Studio demo for the whole thing running.

Managed regions & safe regeneration

Every generated file wraps its body in markers:

// svgrid:managed:start
// Regenerated by SvGrid Studio. Edits inside these markers are overwritten.
...generated code...
// svgrid:managed:end

Re-running generation replaces only the managed region and preserves everything outside it. So you can:

This idempotent regeneration is what makes the generator safe to keep using, rather than a one-shot scaffold you fork away from.

Choosing the data source

The generated +server.ts backend depends on how you scaffold:

Scaffold Backend
--db <dialect> Connected to that driver via process.env.DATABASE_URL.
--sql createSqlDataSource with an execute() stub to fill in.
--from (no --db) In-memory, so the screen runs immediately.

See Databases and Data binding.

Verification

The AI path compiles the generated page (via the Svelte compiler) before handing it back, and the recommended final step everywhere is your project's own check:

npx svelte-check

See also