opencode is a terminal coding agent that can work directly inside an existing SvelteKit project. Once you start it with opencode in the project folder and point it at a clear AGENTS.md, it can add routes, refactor load functions, fix TypeScript errors, and run your test suite. This guide covers a repeatable workflow for SvelteKit teams that want the agent to produce reviewable, tested changes.
Concrete strengths of opencode in SvelteKit projects
SvelteKit gives every route a small set of files with a predictable contract: +page.svelte, +page.server.ts, +page.ts, +layout.server.ts, and +server.ts. opencode reads those files and their imports, so it can make coherent changes across the route boundary instead of editing a single file in isolation. It also understands TypeScript well enough to adjust the generated $types imports and load return types that SvelteKit adds when you run npm run check. Because opencode can execute shell commands, it can run the SvelteKit compiler, Vitest, and Playwright itself and then react to failures, which keeps the loop inside one terminal instead of bouncing between an editor, a test runner, and a browser. That does not remove the need for review, but it does make the agent useful for the mechanical, multi-file edits that SvelteKit projects require.
Prepare the repo with a tight AGENTS.md
opencode reads project instructions from AGENTS.md in the repo root. For SvelteKit work, keep that file short and specific: list the exact commands, the route conventions, and the server/client rules that the agent must respect. Do not rely on the model remembering SvelteKit defaults. For a typical project with Vitest and Playwright already installed, the file can look like this:
# AGENTS.md
## Commands
- Install: `npm install`
- Dev: `npm run dev -- --open`
- Lint: `npm run lint`
- Typecheck: `npm run check`
- Unit tests: `npm run test:unit`
- E2E tests: `npm run test:e2e`
- Build: `npm run build`
## SvelteKit rules
- Routes live under `src/routes/`. Use `+page.svelte` for UI, `+page.server.ts` for server load and form actions, and `+page.ts` for universal load.
- Never import `$env/dynamic/private` or other server-only modules into client files.
- Use `$lib` for shared code. Do not create new top-level folders unless asked.
- Mutations go through form actions, not GET endpoints.
- Keep load functions explicit about return types and let SvelteKit generate `$types`; run `npm run check` after type changes.
## Conventions
- Prefer Svelte 5 runes (`$state`, `$derived`, `$effect`) over legacy stores.
- Use TypeScript interfaces for `PageData` when adding a load function.
- Follow existing formatting; do not reorder imports unless needed.
Putting the commands in AGENTS.md lets opencode run npm run check after a route change without being told every time. The SvelteKit-specific rules prevent the two most common agent mistakes: importing server-only code into +page.svelte and turning a simple mutation into a GET endpoint. A short file is better than a long one; opencode reads the whole file, but very long AGENTS.md files dilute the instructions. For a more detailed walkthrough of opencode itself, see How to use opencode: a step-by-step guide.
A reliable loop for SvelteKit changes
The most reliable loop is: plan the change, ask opencode for a small diff, run the relevant checks, review the diff, and only then move to the next step. For SvelteKit, this usually means one route or one data function at a time. Avoid prompts like ‘add all auth and dashboard pages’; instead, split them into route-level tasks. After each task, run npm run check or the targeted Vitest/Playwright command and inspect the changes with git diff.
Typical prompts that work well in this loop:
- ‘Add a protected route at /dashboard with a
+page.server.tsload that checks the session and redirects to /login if missing. Use the existingrequireUserhelper from$lib/server/auth.ts.’ - ‘Refactor the profile form to use SvelteKit form actions with progressive enhancement and return
failfor invalid input. Update the existing Playwright test to cover a failed submit.’ - ‘Add a Vitest unit test for
parseInvoicein$lib/server/invoices.tsand runnpm run test:unit.’ - ‘Create an API endpoint at
src/routes/api/health/+server.tsthat returns JSON{ status: 'ok' }and add a Playwright smoke test for it.’ - ‘Run
npm run checkand fix all TypeScript errors, then run the full test suite. Do not change any UI text unless it is needed to fix a test.’
Each prompt includes the exact file path or command and the expected behavior. That is what makes opencode fast on SvelteKit: the route files are small and the contract is visible, but the agent still needs the exact path and the specific helper to reuse. After the agent finishes, review the diff with git diff -- src/routes before accepting it.
Where opencode shines and where to review closely
opencode handles route additions, form actions, server endpoints, TypeScript fixes, and small refactors in $lib well. It can also update Vitest mocks and Playwright selectors when the tests are in the repo. Where it needs close review is the SvelteKit boundary between server and client.
Watch for these specifics:
- The agent may import
$env/dynamic/private, Prisma, or other server-only modules into+page.svelteor+page.ts. That breaks the build, but opencode may not notice until you runnpm run buildornpm run check. - Universal load functions and server load functions have different rules. An agent may place
cookies.get()or a database call in+page.tsinstead of+page.server.ts. - Form actions need the
failreturn type anduse:enhanceon the client. The agent may add a<form method="POST">but skipuse:enhance, so the page does a full reload. - SvelteKit’s generated
$typeschange when you add or rename load functions. The agent may not runnpm run checkand leave stalePageDataorActionDatatypes. - If the project uses Svelte 5 runes, the agent may still generate old
onMountor store-based snippets. Tell it in AGENTS.md to use runes and review the diff for legacy patterns.
Most of these are caught by npm run check or npm run build, so the rule is simple: never accept a route-level change without running the compiler and looking at the generated types.
Verifying SvelteKit changes with Vitest and Playwright
Let opencode run the checks, but verify the results against the right command. Vitest is the natural fit for unit testing universal load functions, form actions, and $lib/server helpers because those modules are plain TypeScript once you mock cookies, fetch, and locals. Playwright covers the real browser flows: navigation, form submissions, and redirects after login.
A useful verification table for a SvelteKit change:
| Check | Command | What to look for |
|---|---|---|
| Typecheck and generated types | npm run check | No TS errors in route files, $types updated |
| Unit tests | npm run test:unit | Vitest passes for load functions, actions, helpers |
| E2E smoke | npm run test:e2e | Playwright passes for critical user flows |
| Production build | npm run build | Adapter output completes, no server-only import leaks |
Ask opencode to run the narrowest command that covers the change. For a +server.ts endpoint, run a Playwright API test or the relevant Vitest test; do not start a full e2e run for every small diff. When an agent fixes a test, require it to run that test again before you review the diff. If Playwright is configured with a local dev server, opencode may need to start npm run dev first; mention that in the prompt or add it to AGENTS.md.
Running parallel agents with AgentVera
When one opencode instance is not enough, AgentVera runs real coding agent CLIs, including opencode, side by side in separate terminal panels. For SvelteKit work, the most useful features are per-agent git worktrees so parallel agents do not overwrite the same route files, automatic code review with file:line links after each turn to catch client/server boundary mistakes, and token budgets per agent, turn, and day so multiple agents do not burn through the whole account. Together those make a multi-agent setup safer for a file-based framework like SvelteKit. See Best tools to run AI coding agents in parallel (2026) for more context.
Keep the loop small and review the boundary
opencode is most productive on SvelteKit when you treat it as a fast junior engineer with good typing skills and a short memory. Put the commands and file rules in AGENTS.md, ask for one route or one data change at a time, run the compiler and tests before you review, and watch the server/client boundary. When you need more throughput, use isolated worktrees and a review step rather than letting several agents edit the same src/routes tree.