Skip to content
Back to skills

Svelte

ASecurity

Use when creating or modifying Svelte/TypeScript files under src/frontend/ in a SvelteKit app — routes (+page/+layout), load functions, .svelte components, $lib stores, and server endpoints (+server.ts). Triggers on any .svelte or .ts change under src/frontend/. Covers file-based routing, universal vs server load, the $lib stores hierarchy, the single hooks.server.ts error shaper, and the client/server publish boundary. Generic frontend principles live in the core frontend-fundamentals skill.

  • 6 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 4, 2026
developmenttypescriptshelltestingapifrontend

Works with

  • cli
  • api

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 4, 2026

npx -y skills add kouroshez/coding-os --skill svelte --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Svelte?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Svelte
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/kouroshez-svelte/badge)](https://www.skillsdirectory.com/skills/kouroshez-svelte)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: svelte
tier: stack
domain: [frontend]
description: Use when creating or modifying Svelte/TypeScript files under src/frontend/ in a SvelteKit app — routes (+page/+layout), load functions, .svelte components, $lib stores, and server endpoints (+server.ts). Triggers on any .svelte or .ts change under src/frontend/. Covers file-based routing, universal vs server load, the $lib stores hierarchy, the single hooks.server.ts error shaper, and the client/server publish boundary. Generic frontend principles live in the core frontend-fundamentals skill.
globs: "src/frontend/**/*.{svelte,ts}"
depends_on:
  - clean-code
  - frontend-fundamentals
  - state-management
last_reviewed: "2026-06-14"
---

REQUIRED BACKGROUND: You MUST also follow the core `frontend-fundamentals` and `clean-code` skills. This skill adds SvelteKit-specific conventions on top.

# svelte

## Layer contract (matches `structure.tree`)

| Layer | May import | Never |
|---|---|---|
| `+page.svelte` / components | `$lib` components + stores, `load` data via props | `fetch` in setup, server-only modules, secrets |
| `+page.ts` / `+layout.ts` (universal) | the injected `fetch`, public env | `$env/static/private`, db clients, secrets |
| `+page.server.ts` / `+server.ts` (server) | db clients, private env, secrets | DOM, browser-only APIs |
| `$lib/stores/*.ts` | `svelte/store` primitives | route modules, `load` results |
| `hooks.server.ts` | private env, the logger | per-route business logic |

Components stay presentational — data arrives as props from a `load` function —
so a fetch swap is a `load`-layer-only change and the component is unit-testable
without a network.

## Routing & layout

- File-based routing only — a route is a directory under `routes/` with a
  `+page.svelte`; never hand-wire a client router. Dynamic segments: `routes/users/[id]/+page.svelte`.
- `+layout.svelte` owns shared shell (nav, error boundary) and renders the page
  via `{@render children()}`; keep it a shell, not a logic host.

## Load functions (data ownership)

- `+page.ts` / `+layout.ts` (universal) run on server then client — use the
  injected `fetch`, never the bare global (it double-fetches on hydration and
  skips SvelteKit's relative-URL + cookie handling).
- `+page.server.ts` / `+layout.server.ts` run server-only — the place for db
  clients, `$env/static/private`, and any secret. Their return value is
  serialized to the client, so never return a secret from a server `load`.
- A component never fetches in its `<script>` body; data flows in through the
  `load` result as `data` props.

## Stores & state

- Local component state first (`$state` / plain `let`); cross-component state in
  `$lib/stores` as `writable`/`derived`, one store per file, per the
  state-management skill hierarchy — no module-level mutable singletons.
- Subscribe with the `$store` auto-subscription in components; never manually
  `.subscribe()` without unsubscribing.
- Do not mutate a store from inside a `load` function — `load` returns data,
  stores hold client state.

## Client/server split (the publish boundary)

- Anything a `+page.svelte` imports ships to the browser. Secrets, privileged
  clients, and `$env/static/private` live only in `+page.server.ts`,
  `+server.ts`, and `hooks.server.ts`.
- A `+page.svelte` import of a server-only module is a publish-boundary leak and
  a review-blocking finding.

## Error handling

- ONE central shaper: `hooks.server.ts::handleError` shapes every unexpected
  server error (RFC-9457-style shape per `docs/api-contracts/error-format.md`).
  Log full detail server-side with a reference id; return only a safe message.
- Endpoints (`+server.ts`) and actions throw `error(status, ...)` /
  `fail(status, ...)`; never hand-build an error response body.

## Accessibility

- Interactive elements keyboard-reachable with a visible focus ring; use native
  elements (`<button>`, `<a>`) over `div` + handlers. Provide a skip link and a
  single `<main>` landmark in `+layout.svelte`. The `a11y` core skill is the
  checklist SSOT.

## Testing

- `load` functions: pure unit tests — call the exported `load` with a mocked
  event, assert the returned data; no network.
- Components: @testing-library/svelte, minimal mounting, assert behavior not
  markup; one happy + one error/empty state minimum.
- Server endpoints: invoke the `GET`/`POST` handler directly with a mocked
  request event; never bind a real port in tests.

Files in this skill

  • SKILL.md4.4 KB
  • references/anatomy.md2.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.