Skip to content

feat(templates): add SvelteKit monorepo template - #10

Merged
truehazker merged 6 commits into
mainfrom
feat/sveltekit-template
Aug 2, 2026
Merged

truehazker merged 6 commits into
mainfrom
feat/sveltekit-template

Conversation

@truehazker

@truehazker truehazker commented Aug 1, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds templates/monorepo-svelte/, a Svelte-native counterpart to the existing React monorepo template, and a third option in the create-ely prompt: Monorepo (Svelte).
  • Stack: SvelteKit + Svelte 5 runes, Eden Treaty for end-to-end types against the Elysia backend, Tailwind v4, Biome, and Vitest split into a jsdom project (components) and a node project (load functions / form actions).
  • Feature parity with the React template: SSR user list with cursor pagination and "Load more", a create-user form that works with JavaScript disabled, drawer navigation with active-link state, and an error page.
  • CLI: MONOREPO_TYPES replaces the two binary === MONOREPO ternaries in src/index.ts and src/template.ts, so the next monorepo variant is a list entry instead of another branch. Copy and zip exclusions now also skip dist, build, and .svelte-kit so local test artifacts cannot leak into the published templates.zip.
  • Also aligns the React template's generated backend biome.json schema URL with the 2.5.0 version its root config and workspace dependency already pin (separate commit, unrelated to the Svelte work).

Test plan

  • svelte-check — 0 errors, 0 warnings across 5151 files
  • biome check — clean (run from inside the template; the root config excludes templates/)
  • vitest run — 13 tests passing (8 component in jsdom, 5 server in node)
  • Production build via @sveltejs/adapter-node
  • bun run prepare — rebuilt templates.zip, 724 entries, no node_modules / .svelte-kit / build / dist leakage
  • Full scaffold through setupTemplate('monorepo-svelte', dir) — installs, checks, tests, builds (verified during development, not re-run on the final diff)
  • Live stack: real Elysia backend + Postgres, headless browser — SSR list, paging, enhanced form redirect, 409 handling, and a no-JS form POST (verified during development, not re-run on the final diff)
  • Reviewer: scaffold a fresh project and confirm the Svelte option appears and installs

Notes

Three decisions worth knowing before reviewing:

  • Second git submodule at templates/monorepo-svelte/apps/backend, pinned to the same commit as the React template's. A symlink was tried first and fails — Bun workspaces do not resolve elysia-boilerplate through a symlink, so an in-repo bun install errors out. The cost is that a backend bump must update both submodules, now documented in CONTRIBUTING.md.
  • src/hooks.server.ts is load-bearing. SvelteKit hides SSR response headers unless they are allowlisted, and Eden reads content-type to decide how to parse the body. Without that hook every SSR load of /users fails.
  • The src alias lives in svelte.config.js, not tsconfig.json. Putting it in tsconfig paths would clobber the generated $lib paths; Eden cannot resolve the backend App type without it either way.

Deliberately skipped: shadcn (configured-but-unused and broken in the React template), vitest-browser-svelte (downloads a Playwright browser on install, wrong for a scaffold), and Elysia's SvelteKit integration (it mounts Elysia inside a catch-all +server.ts, which would discard the backend's standalone Docker/migrate/OpenAPI deployment model — that would be a separate fullstack-svelte template, not a change to this one).

No version bump or CHANGELOG entry is included — cut that separately with /release if this should ship.

Co-Authored-By: Skrrt Bot bot@skrrt.sh

Summary by CodeRabbit

  • New Features

    • Added a SvelteKit/Svelte 5 monorepo template alongside the existing React option.
    • Included user listing, pagination, user creation, navigation, API integration, and error handling.
    • Added ready-to-use development, testing, and build configurations.
  • Documentation

    • Updated setup guides and project documentation for both monorepo variants.
  • Tests

    • Added coverage for user workflows, pagination, validation, errors, and form submissions.

truehazker and others added 2 commits August 2, 2026 00:13
Adds `templates/monorepo-svelte/`, a Svelte-native counterpart to the
existing React monorepo: SvelteKit with Svelte 5 runes, Eden Treaty for
end-to-end types, Tailwind v4, and Vitest split into jsdom (component)
and node (load/action) projects.

Two pieces are load-bearing and easy to break later:

- `hooks.server.ts` allowlists the `content-type` response header.
  SvelteKit hides SSR response headers and Eden reads that header to
  decide how to parse the body, so every SSR load of `/users` fails
  without it.
- `svelte.config.js` aliases `src` to `../backend/src` in the kit config
  rather than in tsconfig `paths`, which would clobber the generated
  `$lib` paths. Eden cannot resolve the backend `App` type without it.

The backend is a second git submodule pinned to the same commit as the
React template's, not a symlink: Bun workspaces do not resolve
`elysia-boilerplate` through a symlink, so an in-repo `bun install`
fails. The cost is that a backend bump must now update both submodules,
which CONTRIBUTING.md documents.

On the CLI side, `MONOREPO_TYPES` replaces the two binary
`=== MONOREPO` ternaries so a future monorepo variant is a list entry
instead of another branch. Copy and zip exclusions now also skip
`dist`, `build`, and `.svelte-kit` so local test artifacts cannot leak
into the published templates.zip.

Verified: svelte-check 0 errors / 0 warnings, Biome clean, 13 Vitest
tests passing, production build via adapter-node, and a rebuilt
templates.zip with no build artifacts.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…version

The generated `apps/backend/biome.json` declared the 2.3.10 schema while
the monorepo root config it extends, and the workspace `@biomejs/biome`
devDependency, are both on 2.5.0. The URL only drives editor hints, so
nothing was broken, but the stale version advertises the wrong option
set on hover and completion.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@truehazker, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 55 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6785e603-4366-469b-a0dc-fe29be916add

📥 Commits

Reviewing files that changed from the base of the PR and between 776f425 and f5b7024.

📒 Files selected for processing (4)
  • src/index.ts
  • templates/monorepo-svelte/apps/frontend/src/lib/api.ts
  • templates/monorepo-svelte/apps/frontend/src/routes/users/+page.ts
  • templates/monorepo-svelte/apps/frontend/src/routes/users/new/+page.server.ts
📝 Walkthrough

Walkthrough

The project adds a SvelteKit monorepo template beside the React variant. It updates template selection and setup logic, adds Svelte frontend and backend configuration, implements typed user flows, and documents the new template.

Changes

Svelte monorepo support

Layer / File(s) Summary
Template selection and setup
src/*, scripts/prepare.ts, package.json, README.md, CONTRIBUTING.md
The CLI recognizes React and Svelte monorepo variants. Setup logic, exclusions, keywords, and documentation support both variants.
Svelte workspace foundation
templates/monorepo-svelte/*, templates/monorepo-svelte/apps/backend*, templates/monorepo-svelte/apps/frontend/*, templates/monorepo/apps/backend*
The new template adds Bun workspace configuration, backend submodule wiring, Biome settings, SvelteKit tooling, environment configuration, styling, and application shell components.
Typed user API and routes
templates/monorepo-svelte/apps/frontend/src/lib/*, templates/monorepo-svelte/apps/frontend/src/routes/*, templates/monorepo-svelte/apps/frontend/src/hooks.server.ts
The frontend adds Eden Treaty API access, paginated user listing, user creation actions, form handling, error states, and route rendering.
Route and API validation
templates/monorepo-svelte/apps/frontend/src/routes/**/*.test.ts, templates/monorepo-svelte/apps/frontend/src/lib/components/*.test.ts
Tests cover API pagination, error handling, user creation, redirects, rendered route states, and header drawer behavior.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant UsersPage
  participant fetchUsers
  participant ElysiaAPI
  participant CreateUserAction
  UsersPage->>fetchUsers: Request users with cursor
  fetchUsers->>ElysiaAPI: GET paginated users
  ElysiaAPI-->>fetchUsers: Return users or error
  CreateUserAction->>ElysiaAPI: POST user form data
  ElysiaAPI-->>CreateUserAction: Return creation result
  CreateUserAction-->>UsersPage: Redirect to /users on success
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the addition of the SvelteKit monorepo template.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/sveltekit-template

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CONTRIBUTING.md`:
- Around line 49-56: Add `set -euo pipefail` immediately before the backend
update loop in the documented shell snippet, so any failed fetch or checkout
stops execution before staging an incomplete submodule update.

In `@templates/monorepo-svelte/.gitignore`:
- Around line 25-28: Reorder the local environment rules so the `.env.*`
wildcard appears before the `!.env.example` exception, allowing `.env.example`
to remain unignored while other environment files stay ignored.

In `@templates/monorepo-svelte/apps/backend`:
- Line 1: Update the apps/backend submodule gitlink in the Svelte monorepo
template to a commit reachable from its configured remote, or correct the
submodule remote configuration so commit
007a897a8ebae837699910f30cf733181035c48c can be fetched. Verify git submodule
update succeeds after the change.

In `@templates/monorepo-svelte/apps/frontend/src/app.css`:
- Around line 5-7: Update the body font-family declaration in app.css by adding
an empty line before it, removing quotes from the single-word font names Roboto,
Oxygen, Ubuntu, and Cantarell, and preserving quotes around font names
containing spaces.

In `@templates/monorepo-svelte/apps/frontend/src/lib/components/Header.svelte`:
- Around line 27-31: Update the drawer `<aside>` controlled by `isOpen` so that
when closed it is inert and excluded from assistive technology, while preserving
its existing focusable controls and visibility when open. Use the component’s
existing open-state binding to apply the appropriate inert and hidden
accessibility attributes.

In `@templates/monorepo-svelte/apps/frontend/src/routes/users/new/`+page.svelte:
- Around line 9-14: Update the submit handler around submit so submitting
remains true while update() runs, and reset it only after the awaited update
completes. Preserve the existing async form-action update flow while keeping the
submit button disabled throughout processing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 6cdcf26f-9c8d-4d8c-8fa4-1497d50f726b

📥 Commits

Reviewing files that changed from the base of the PR and between 55ca92d and 557f1ad.

⛔ Files ignored due to path filters (2)
  • templates/monorepo-svelte/apps/frontend/static/favicon.ico is excluded by !**/*.ico
  • templates/monorepo-svelte/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (38)
  • .gitmodules
  • CONTRIBUTING.md
  • README.md
  • package.json
  • scripts/prepare.ts
  • src/constants.ts
  • src/index.ts
  • src/template.ts
  • templates/monorepo-svelte/.gitignore
  • templates/monorepo-svelte/README.md
  • templates/monorepo-svelte/apps/backend
  • templates/monorepo-svelte/apps/backend-biome.json.template
  • templates/monorepo-svelte/apps/frontend/.env.example
  • templates/monorepo-svelte/apps/frontend/.gitignore
  • templates/monorepo-svelte/apps/frontend/README.md
  • templates/monorepo-svelte/apps/frontend/biome.json
  • templates/monorepo-svelte/apps/frontend/package.json
  • templates/monorepo-svelte/apps/frontend/src/app.css
  • templates/monorepo-svelte/apps/frontend/src/app.d.ts
  • templates/monorepo-svelte/apps/frontend/src/app.html
  • templates/monorepo-svelte/apps/frontend/src/hooks.server.ts
  • templates/monorepo-svelte/apps/frontend/src/lib/api.ts
  • templates/monorepo-svelte/apps/frontend/src/lib/components/Header.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/+error.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/+layout.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/+page.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/users/+page.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/users/+page.ts
  • templates/monorepo-svelte/apps/frontend/src/routes/users/new/+page.server.ts
  • templates/monorepo-svelte/apps/frontend/src/routes/users/new/+page.svelte
  • templates/monorepo-svelte/apps/frontend/src/routes/users/users.svelte.test.ts
  • templates/monorepo-svelte/apps/frontend/src/routes/users/users.test.ts
  • templates/monorepo-svelte/apps/frontend/svelte.config.js
  • templates/monorepo-svelte/apps/frontend/tsconfig.json
  • templates/monorepo-svelte/apps/frontend/vite.config.ts
  • templates/monorepo-svelte/biome.json
  • templates/monorepo-svelte/package.json
  • templates/monorepo/apps/backend-biome.json.template

Comment thread CONTRIBUTING.md Resolved
Comment thread templates/monorepo-svelte/.gitignore Resolved
Comment thread templates/monorepo-svelte/apps/backend Resolved
truehazker and others added 3 commits August 2, 2026 00:29
Four fixes from the PR #10 review:

- `.gitignore`: `!.env.example` sat above the `.env.*` wildcard, and the
  last matching rule wins, so `.env.example` was ignored and could not be
  committed from a scaffolded project. Moving the negation below the
  wildcard flips it from ignored to trackable. The React template had the
  same ordering, so both are fixed.
- `Header.svelte`: the closed drawer was only translated off-screen, so
  its close button and nav links stayed in the tab order and in the
  accessibility tree. `inert={!isOpen}` removes them while it is closed.
- `users/new/+page.svelte`: `submitting` was cleared before `await
  update()` rather than after, briefly re-enabling the submit button
  while the action result was still being applied. Moving the reset into
  a `finally` keeps the form disabled for the whole cycle.
- `CONTRIBUTING.md`: the submodule bump snippet ran `git add` even when a
  fetch or checkout failed, so it could commit the two backends at
  different commits. The loop and the commit now share a `set -e`
  subshell, which fails fast without leaking `set -e` into the reader's
  interactive shell.

Adds a Header test covering the drawer's inert state, since a regression
there is invisible — the links still render, they just become reachable
again by keyboard. Verified by mutation: dropping the attribute fails it.

Not changed: CodeRabbit flagged the `apps/backend` gitlink as pointing at
an unreachable commit, but `007a897` is exactly the `v0.7.0` tag on the
elysia-boilerplate remote (confirmed with `git ls-remote`), so it fetches
fine. Its Stylelint findings on `app.css` are also skipped — this project
formats CSS with Biome, ships no Stylelint config, and quoted font names
are valid CSS.

Verified: svelte-check 0 errors / 0 warnings, Biome clean, 14 Vitest
tests passing, production build, and a rebuilt templates.zip with no
build artifacts.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Moves both monorepo templates from v0.7.0 (`007a897`) to v0.8.0
(`6bcef6a`), following the procedure in CONTRIBUTING.md so the two
submodules stay on the same commit.

v0.8.0 carries two backend changes: `SERVER_HOSTNAME` now defaults to
`0.0.0.0` instead of `localhost` (with the OpenAPI server URL still
rendering `localhost`, since `0.0.0.0` is a bind address rather than a
reachable one), and pino now emits string level labels for Grafana.
Nothing under `src/modules` or `src/db` changed, so the Eden Treaty
`App` type and the users API are identical and neither frontend needed
a change. `PUBLIC_API_URL=http://localhost:3000` still reaches a backend
bound to `0.0.0.0`.

Only the Svelte lockfile moved. Bun records the workspace version in
`bun.lock` but resolves the package by path, so it rewrites that field
opportunistically; the React lockfile still reads 0.6.0, which it
already did before this bump. Left alone deliberately — the field is
informational, and forcing a regeneration would churn unrelated
dependency resolutions.

Verified against v0.8.0: Svelte template svelte-check 0 errors / 0
warnings, Biome clean, 14 Vitest tests, adapter-node build; React
template 7 Vitest tests and `vite build && tsc`. templates.zip rebuilt
with no build artifacts.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Deleted and rebuilt all three lockfiles owned by this repo, since several
fields had drifted from what the manifests actually declare. The two
lockfiles under `apps/backend` belong to the elysia-boilerplate submodule
and were left untouched.

The root lockfile still recorded the package as `create-elysiajs`, the
name from before the rename to `create-ely`. It also carried older
resolutions for `adm-zip` (0.5.16 to 0.5.18), `@types/bun`, `@types/node`,
and `undici-types`.

The React template's lockfile claimed backend version 0.6.0 while its
submodule had been on 0.7.0 and is now on 0.8.0. Bun resolves a workspace
by path rather than version, so it never rewrote that field on its own.
Regenerating also refreshed transitive resolutions there, mostly patch
bumps across babel, csstools, emnapi, and oxc.

The Svelte template's lockfile rebuilt byte-identical, so only the other
two are in this commit. Both templates now resolve every shared
dependency to the same version: elysia 1.4.29, eden 1.4.9, Biome 2.5.0,
TypeScript 6.0.3, Vite 8.2.0, and Vitest 4.1.10.

Verified after regenerating: React template 7 tests and `vite build &&
tsc`; Svelte template svelte-check 0 errors / 0 warnings, Biome clean, 14
tests, adapter-node build; CLI Biome clean and `bun run prepare` still
writes a 725-entry templates.zip with no build artifacts. Also scaffolded
all three templates end to end through `setupTemplate`, then ran the
generated Svelte app's own check, tests, and build against the refreshed
lockfile. That scaffold doubles as a check on the earlier `.gitignore`
fix: `apps/frontend/.env.example` now reports as untracked rather than
ignored in a fresh project.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@truehazker

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 1, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@truehazker

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

CodeRabbit's docstring coverage check reported 50% on this branch, below
the 80% threshold. Add JSDoc to the functions in the changed files that
were still missing it: `fetchUsers`, the users `load` function, the user
creation form action, and the CLI `main` entrypoint.

No behavior changes.

Co-Authored-By: Skrrt Bot <bot@skrrt.sh>
@truehazker
truehazker merged commit d939b52 into main Aug 2, 2026
2 checks passed
@truehazker truehazker mentioned this pull request Aug 2, 2026
2 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant