This skill defines design conventions for keeping SvelteKit screens, route handling, and server processing separate.
kf-g-sveltekit-docs using the official specification as the reference source, and this skill fixes the responsibility separation decisions used in the repo.
When to use
- Designing the screen structure of SvelteKit
+page.svelteと+page.server.tsseparating the responsibilities ofloadやactionsjudging the amount of processing to write in- Deciding where to place DB access, external APIs, authentication, and business logic
- Deciding the placement of route-local components and shared components
- Reviewing existing SvelteKit implementations and fixing crossed responsibilities
How to proceed with reading
- If SvelteKit file conventions,
load、actions, and the server-only modules specification are involved, first read../kf-g-sveltekit-docs/SKILL.mdread .svelteIf .svelte components or Svelte 5 writing styles are involved,../svelte-core-bestpractices/SKILL.mdalso read- If CSS layout or the responsibility boundaries of UI terminology are the main topic, use the relevant CSS / design-system skill together
- This skill judges responsibility separation in implementation, not the official specification itself
Golden rules
Treat SvelteKit file names as responsibility boundaries.
If unsure,+page.server.ts keep it as a thin intermediary and move the actual processing to $lib/server toward
| Location | Role | What to do | What to avoid |
|---|---|---|---|
+page.svelte |
View | Data display, detection of user operations such as forms and buttons, local UI state | API communication, DB access, authentication checks, long calculations, business rules |
+page.server.ts |
Controller | load、actions, receiving input, calling services,redirect / error / fail, formatting into the shape returned to the screen |
Writing DB queries directly, calling external APIs directly, heavy business logic, processing reused across multiple screens |
$lib/server/ |
Model / Service | DB access, external API integration, authentication checks, business rules, persistence, transaction boundaries | Dependencies on components or client modules used from the browser |
+page.svelte Rules for
- Screens are the place to display
data, props, and local state - User operations may be detected
- Form submissions flow to SvelteKit's
actionstoward - Push complex processing to
loada service before, or a small pure helper - Do not import private env or DB clients
- Do not write fetch or external API calls directly
Acceptable processing:
- Light formatting for display
- UI state such as opening/closing input fields, selection state, and sort display
use:enhanceProgressive enhancement such as- Passing props to child components
+page.server.ts Rules for
+page.server.ts should focus on traffic control between screens and server services.
If it gets long, return it to the form of "calling from here" rather than "executing processing here".
Processing that may be written:
loadとactionsparams、locals、request、formDataReceiving- Minimal input validation and type conversion
$lib/serverservice call inredirect、error、failSvelteKit boundary handling via- Thin shaping into the return values the screen needs
Processing to avoid:
- Directly writing SQL or ORM queries
- Directly writing external API clients
- Business decisions such as authorization rules and pricing calculations
- Processing likely to be reused across multiple routes
- Core logic you want to test
- Huge
actionsbranch
Criteria:
- If you want to unit test that processing, move it to
$lib/servermove to - If it seems likely to be used even if the route changes, move it to
$lib/servermove to - If it reads the DB, an external API, private env, or authentication state, make
$lib/serverthe first candidate +page.server.tsLeave only "which service to call and how to connect to SvelteKit" in
$lib/server/ rules for
$lib/server/ is the server-only application core.
Separate it from UI and route files, and cut it out as easily testable functions.
What to put here:
- DB repository や query helper
- External API clients
- Authentication, authorization, permission checks
- Business rules
- Save, update, delete, and transaction processing
- Server-side use cases shared across multiple routes
Guideline for how to split:
src/lib/server/<domain>/service.ts: business processing called from screens or use casessrc/lib/server/<domain>/repository.ts: DB reads and writessrc/lib/server/<domain>/schema.ts: schemas for server-side input validation and persistencesrc/lib/server/<provider>/client.ts: external API clients
Exceptions:
- A small server-only helper used by only one route can be placed under the same route in
*.server.tsmay be acceptable - However, once that helper grows, move it to
$lib/servermove to
Component placement rules
Components are placed based on "where they are used."
Do not gather everything in src/lib/components do not gather into.
Route-local component
Placement:
src/routes/<route>/ComponentName.svelte- If the number grows,
src/routes/<route>/components/ComponentName.svelte
What to put here:
- Display parts used only by that route
- Forms, lists, headers, and filters specific to that screen
- route の
dataUI strongly dependent on types or screen-specific props
Things to avoid:
- Do not import from other routes
- Do not confine generic buttons or dialogs to route-local
Shared component
Placement:
src/lib/components/ComponentName.svelte- If necessary by UI type or domain,
src/lib/components/<group>/ComponentName.svelte
What to put here:
- UI used by multiple routes
- Reusable parts such as Button, Dialog, Navigation, and FormField
- Components close to a design system
- Display components that do not depend on routes
Things to avoid:
- Do not bring in assumptions specific to a particular route's
datado not bring in assumptions - Do not mix in screen-specific business workflows
Import direction
Keep the dependency direction one-way.
+page.svelte
-> route-local components
-> $lib/components
+page.server.ts
-> $lib/server/<domain>
$lib/server/<domain>
-> DB / external API / auth / domain rules
Dependencies to avoid:
- From shared component to route-local component
Review perspectives
When looking at a SvelteKit implementation, check the following.
+page.sveltewhether API communication, DB, authentication, and business decisions are not mixed in+page.server.tswhether it is bloated with actual processing rather than service calls- Are DB, external APIs, authentication, and business rules in
$lib/server? - whether components specific to that screen are colocated under the route
- whether components used across multiple screens are in
$lib/components? - whether shared components do not depend on route-specific types
- whether the import direction is one-way
Output policy during implementation
- If you have fixed the separation of responsibilities, briefly explain what you
+page.svelte、+page.server.ts、$lib/server, and what you separated into components - If the official specification is the point at issue,
kf-g-sveltekit-docswrite based on the confirmation results of - For small screens, prioritize a thin controller and clear service functions over excessive abstraction
- If an existing directory structure exists, respect that structure
Final check
+page.sveltewhether it can be read as a View+page.server.tswhether it can be read as a Controller$lib/serverwhether it can be read as a server-only Model / Service- whether the placement of route-local components and shared components is separated by purpose
- whether you are not asserting SvelteKit-specific specifications from memory alone