The App Starter is the official template for creating a new Laioutr app. It gives you a minimal Nuxt module structure, Laioutr registration, two playgrounds for development, and the conventions you need so your app works with Laioutr’s Frontend Core, Orchestr, and Studio.
Use the App Starter when you want to:
If you are new to Laioutr, read What is Laioutr? and Apps in Laioutr first. Then follow Setup Local Development Environment to clone the starter and run it locally.
A Laioutr app is a Nuxt module that:
registerLaioutrApp from @laioutr-core/kit to register with Laioutr (orchestr dirs, sections, blocks, page wrappers, etc.).my-laioutr-app or @laioutr-app/shopify) so configuration from laioutrrc.json is passed into the module by name.The App Starter is a minimal implementation of this: it registers orchestr dirs and section/block paths, installs the right peer modules on prepare, and leaves orchestr handlers and section/block implementations for you to add.
Clone or download the template from GitHub:
npx giget@latest gh:laioutr/app-starter
cd app-starter
Or clone the repo directly:
git clone https://github.com/laioutr/app-starter.git
cd app-starter
You don’t have to use this template, but it gives you the expected layout, scripts, and Laioutr registration so you can focus on your app logic.
After opening the App Starter, you’ll see a structure like this:
| Path | Purpose |
|---|---|
src/module.ts | Nuxt module entry. Defines configKey (must match package.json name), registerLaioutrApp (orchestr dirs, sections, blocks), runtime config, and optional installModule for peer deps. |
src/globalExtensions.ts | TypeScript module augmentation for Nuxt runtime config and Vue so your app’s config key is typed. |
src/runtime/server/orchestr/ | Orchestr handlers live here: e.g. product/by-slug.query.ts, cart/add-item.action.ts, menu/base.resolver.ts. The starter only adds a plugins/ (e.g. Zod fix) and leaves entity folders for you. |
src/runtime/app/sections/ | Vue components and definitions for sections (Studio). Starter ships an empty folder with a .gitkeep. |
src/runtime/app/blocks/ | Vue components and definitions for blocks (Studio). Starter ships an empty folder with a .gitkeep. |
playground/ | A Nuxt app that uses your module and a laioutrrc.json (or mock) to develop the full UI with Frontend Core. Run with pnpm dev. |
orchestr-playground/ | A Nuxt app focused on orchestr: it includes Orchestr and Orchestr DevTools so you can test queries and actions (e.g. via the Orchestr Request Editor). Run with pnpm orchestr-dev. |
test/ | Basic module tests (e.g. Vitest). |
Important details:
configKey in module.ts must equal the package name in package.json (e.g. my-laioutr-app). Laioutr passes app config from laioutrrc.json by this key. See App Configuration.registerLaioutrApp({ orchestrDirs: [...] }). Adding or changing files under those dirs is how you add queries, actions, links, and resolvers.registerLaioutrApp({ sections: [...], blocks: [...] }). Each section/block needs a definition export so Studio can list and configure it.Before you start:
laioutrrc.json and testing with Studio)..npmrc.config as .npmrc and set NPM_LAIOUTR_TOKEN; you can find the token in project settings.Optional but recommended: install the Laioutr CLI to fetch and update laioutrrc.json:
pnpm add -g @laioutr/cli@latest
pnpm install
laioutr rc fetch -p <organization-slug>/<project-slug> -s <project-secret>
If you don’t use the CLI, create or copy a laioutrrc.json at the project root. The playground can import it (see playground/nuxt.config.ts); the orchestr-playground typically doesn’t need a full laioutrrc for testing orchestr only.
pnpm dev:prepare
pnpm dev # UI playground (Frontend Core + laioutrrc)
pnpm orchestr-dev # Orchestr playground (queries/actions + DevTools)
After that you can:
Detailed steps and troubleshooting are in Setup Local Development Environment.
package.json, set name, description, and repository. Use Find & Replace (e.g. “My Laioutr App” → your app name, my-laioutr-app → your package name). Ensure module.ts uses the same name for configKey (via name from package.json).module.ts, extend ModuleOptions and RuntimeConfigModulePublic / RuntimeConfigModulePrivate in globalExtensions.ts. Merge options into nuxt.options.runtimeConfig[name] and nuxt.options.runtimeConfig.public[name] so components and server code can read config. See App Configuration.src/runtime/server/orchestr/, e.g. product/by-slug.query.ts, cart/add-item.action.ts, menu/base.resolver.ts. Use the same patterns as in existing apps (e.g. define a middleware like defineMyApp that provides a client and context, then use defineMyAppQuery, defineMyAppAction, etc.). Canonical types live in @laioutr-core/canonical-types. The starter’s orchestr/plugins/zodFix.ts applies a Zod compatibility fix; keep it unless you don’t use Zod in orchestr.src/runtime/app/sections/ and src/runtime/app/blocks/. Each must export a definition so Frontend Core and Studio can register them. See the local-setup guide section “Adding ui sections and blocks”.registerLaioutrApp({ pageWrapper: ['YourWrapperComponent'] }) and add that component under runtime/app/components/.apps[].config for the entry whose name matches your package name.configKey must be the package name so Laioutr can pass the right slice of laioutrrc.json into your module’s setup(options, nuxt).For deeper dives, see Architecture, Extensibility, and the Orchestr docs.
laioutrrc.json and runtime config work for your app.laioutrrc.json.