Skip to content

Recipes and implementation decisions ​

These recipes use fictional Catalog/Identity features. They demonstrate responsibilities rather than importing another application's production code.

Add a feature without guessing where files go ​

  1. Name the business context (Catalog), aggregate (Product), app boundary (Public) and scope (Shopping) independently.
  2. Generate a read feature with CLI; request DTO schemas only when the operation has input requiring validation.
  3. Inspect the resource/port and datasource response mapping against your backend contract.
  4. Confirm CompositionRoot wiring and inject the use-case interface into the presenter.
  5. Render through a signal/form in the component. Keep transport details out of the template.

Follow the complete composition example. It deliberately uses explicit forwarding before introducing ClassMirror, so every dependency is visible.

Current user from middleware to a reactive class ​

Use server middleware to authenticate and obtain a public user snapshot. Write that snapshot to RequestContext.state, not an unscoped module store. A synchronous useBoot callback puts it into a singleton RegisterProvider-backed Svelte class during SSR and first hydration. See the full state example.

Do not transfer session tokens, cookies, private permissions internals or the whole request event. Once serialized into the HTML, a value is visible to the browser. After hydration, update client state explicitly after login/logout; a later server request does not automatically resynchronize the boot snapshot.

Distinguish a resource from an action ​

A presenter read method can call createAsyncResource; a write method can call createAsyncAction. Both use the application error policy, but their return/throw semantics differ. A component's createAsyncSignal owns reactive request status; createActiveForm owns editable values and submission state. They are different layers, not interchangeable names for fetch.

See delivery helpers and reactive APIs. When passing a presenter method as a callback, use a closure or bindMethods; otherwise JavaScript may lose this.

SSR data or client-only data? ​

Use an awaited server signal with a stable data-specific key when its response must appear in initial SSR HTML. Its callback must remain valid on client navigation/refresh; hydratable is serialization, not a server RPC boundary. Use a server endpoint/remote function for server-only operations. See signals.

Use a regular client signal for interactive, nonessential data. Its initial pending state can keep a linked form waiting without inventing an SSR request. Use SvelteKit load when route-specific HTTP behavior, redirects or server-only dependencies make it the clearer boundary.

Translations without manual lifecycle wrappers ​

Create one TranslationManager registration and pass it to app.useTranslations. The app manages server preload, locale synchronization and client initialization. Export t from that manager for convenient component imports; do not snapshot translated strings into module-level constants. Translation guide.

UI behavior without mixing infrastructure ​

Open a lazy modal from a presenter/action success handler or component, not from a repository. UI-kit supports module/promise component sources and asynchronous show. Put Slider/Cropper styles in the UI layer; use zoom/animation attachments where browser interaction belongs. UI-kit.

Common mistakes ​

SymptomInspect first
Missing request contextResolution happened at module scope or outside a Kit-managed request
State resets on each accessor call in the browserRegisterProvider defaults to scoped, which is per-call in the browser
User state leaksA mutable instance/result was cached outside request scope
A page loads all feature modulesStatic imports/global barrels; lazy constructors alone do not split code
Translations stay in the old languageA translation was evaluated once outside a reactive read
Helpers fail presenter namingUpgrade CLI to the explicit presenter-marker rules
Composite response types fail Resource namingPut constituent types under the named resource directory; use current CLI
Enum in ApiResponse is rejected by filenameCurrent CLI checks Enum filenames only within Enums directories

A practical verification checklist ​

Test interface-based use cases with fakes; test adapters with representative backend envelopes; test two concurrent SSR users and two locales; test first hydration separately from subsequent navigation; test error/retry and aborted requests; build for the actual adapter. Run CLI architecture checks and the compiler, but do not interpret a green lint result as proof of no leaks or production correctness.