Skip to content

feat: warn when using a .server. file or file inside a server directory without importing a server-only module#16266

Merged
Rich-Harris merged 4 commits into
version-3from
package-server-only-warning
Jul 10, 2026
Merged

feat: warn when using a .server. file or file inside a server directory without importing a server-only module#16266
Rich-Harris merged 4 commits into
version-3from
package-server-only-warning

Conversation

@dummdidumm

@dummdidumm dummdidumm commented Jul 7, 2026

Copy link
Copy Markdown
Member

#12529 was opened a while ago, and since then things have changed. We do check all files now, but we do not error on .server. files or files inside server directories if they're outside the cwd.

We decided we want to keep that logic. Things outside it (or inside node_modules) still will fail if they e.g. import $app/server or $app/env/private. We decided that this is the desired behavior - and it already is that way today. This PR therefore only adds additional validation to @sveltejs/package to hint at this, and thereby closes #12529

We said we may investigate creating an npm package which you can also use and establish it as somewhat of a standard across the Vite ecosystem, but that will happen separately.

…ectory without importing a server-only module

#12529 was opened a while ago, and since then things have changed. We do check _all_ files now, but we do not error on `.server.` files or files inside `server` directories if they're outside the cwd.

We decided we want to keep that logic. Things outside it (or inside node_modules) still will fail if they e.g. import `$app/server` or `$app/env/private`. We decided that this is the desired behavior. This PR therefore only adds additional validation to `@sveltejs/package` to hint at this, and thereby closes #12529

We said we may investigate creating an npm package which you can also use and establish it as somewhat of a standard across the Vite ecosystem, but that will happen separately.
@pkg-svelte-dev

pkg-svelte-dev Bot commented Jul 7, 2026

Copy link
Copy Markdown

Install the latest version of @sveltejs/kit from 09c3b44:

pnpm add https://pkg.svelte.dev/@sveltejs/kit/c/09c3b443d8313c76b85a24dbff44c89b1dddcf3d

Open in pkg.svelte.dev: https://pkg.svelte.dev/repos/kit/pr/16266

@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 09c3b44

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@sveltejs/package Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@svelte-docs-bot

Copy link
Copy Markdown

Comment thread packages/package/src/validate.js Outdated
Comment on lines +82 to +83
const is_server_only = name.includes('.server.') || /(^|\/)server\//.test(name);
unprotected_server_only_files.set(name, is_server_only && !has_guard_import);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

couldn't this be a Set?

Suggested change
const is_server_only = name.includes('.server.') || /(^|\/)server\//.test(name);
unprotected_server_only_files.set(name, is_server_only && !has_guard_import);
if (!has_guard_import && (name.includes('.server.') || /(^|\/)server\//.test(name))) {
unprotected_server_only_files.add(name);
}

@Rich-Harris

Copy link
Copy Markdown
Member

Should we account for transitive deps? You can imagine a scenario like this:

// src/server/api.js
import { db } from './db.js';

export function getThings() {
  return db.select().from(things);
}
// src/server/db.js';
import { DATABASE_URL } from '$app/env/private';
import { createClient } from 'database-library';

export const db = createClient(DATABASE_URL);

api.js is protected, but we can't determine that in isolation. A warning here would be annoying; I don't want to add a phantom import for no reason.

Comment thread packages/package/src/validate.js
@teemingc teemingc linked an issue Jul 9, 2026 that may be closed by this pull request
Comment thread packages/package/src/validate.js Outdated

@Rich-Harris Rich-Harris left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

small suggestion but otherwise LGTM

Co-authored-by: Rich Harris <richard.a.harris@gmail.com>
@Rich-Harris

Copy link
Copy Markdown
Member

/autofix

@Rich-Harris
Rich-Harris merged commit 065ce4a into version-3 Jul 10, 2026
17 of 18 checks passed
@Rich-Harris
Rich-Harris deleted the package-server-only-warning branch July 10, 2026 19:13
Rich-Harris pushed a commit that referenced this pull request Jul 14, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to version-3, this PR
will be updated.

⚠️⚠️⚠️⚠️⚠️⚠️

`version-3` is currently in **pre mode** so this branch has prereleases
rather than normal releases. If you want to exit prereleases, run
`changeset pre exit` on `version-3`.

⚠️⚠️⚠️⚠️⚠️⚠️

# Releases
## @sveltejs/kit@3.0.0-next.8

### Major Changes

- breaking: remove `experimental.handleRenderingErrors` flag
([#16265](#16265))

- breaking: make `getRequest` and `setResponse` synchronous
([#16280](#16280))

- breaking: make `page.url` immutable on a type level
([#16256](#16256))

- breaking: add `refreshAll` and deprecate `invalidateAll`
([#16289](#16289))

### Minor Changes

- feat: allow hyphens in param and matcher names
([#16284](#16284))

- feat: add `ErrorProps` to generated types
([#16272](#16272))

### Patch Changes

- fix: detect destructured `load` and `actions` exports during type
generation ([#16329](#16329))

- fix: ensure CSS URL references are absolute when `paths.relative` is
`false` ([#16315](#16315))

- fix: exclude deleted cookies from `cookies.getAll()` so it stays
consistent with `cookies.get()`
([#16297](#16297))

- fix: reset failed `<svelte:boundary>` on client navigation so a stale
`+error.svelte` is torn down
([#16296](#16296))

- fix: preserve shared client chunk hashes when the app version changes
([#16324](#16324))

- fix: align MAX_COOKIE_SIZE with RFC 6265bis
([#16322](#16322))

- fix: use mouseover+mousemove for preloading to reduce events
([#16325](#16325))
## @sveltejs/package@3.0.0-next.2

### Minor Changes

- feat: warn when using a `.server.` file or file inside a `server`
directory without importing a server-only module
([#16266](#16266))
## @sveltejs/adapter-auto@8.0.0-next.1

### Patch Changes

- fix: allow prerelease versions of SvelteKit 3 to satisfy the peer
dependency range ([#16286](#16286))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8
## @sveltejs/adapter-cloudflare@8.0.0-next.2

### Patch Changes

- fix: allow prerelease versions of SvelteKit 3 to satisfy the peer
dependency range ([#16286](#16286))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8
## @sveltejs/adapter-netlify@7.0.0-next.3

### Patch Changes

- fix: include `utils.js` in package.json `files`
([#16298](#16298))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8
## @sveltejs/adapter-node@6.0.0-next.3

### Patch Changes

- fix: allow prerelease versions of SvelteKit 3 to satisfy the peer
dependency range ([#16286](#16286))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8
## @sveltejs/adapter-static@4.0.0-next.1

### Patch Changes

- fix: allow prerelease versions of SvelteKit 3 to satisfy the peer
dependency range ([#16286](#16286))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8
## @sveltejs/adapter-vercel@7.0.0-next.2

### Patch Changes

- fix: allow prerelease versions of SvelteKit 3 to satisfy the peer
dependency range ([#16286](#16286))
- Updated dependencies
[[`737d119`](737d119),
[`fa78efb`](fa78efb),
[`07c207e`](07c207e),
[`a47071b`](a47071b),
[`14d7d5a`](14d7d5a),
[`5c38e51`](5c38e51),
[`0702baa`](0702baa),
[`e1938c6`](e1938c6),
[`8293144`](8293144),
[`f76d7d9`](f76d7d9),
[`ab5c253`](ab5c253),
[`b557b1b`](b557b1b),
[`4a513e2`](4a513e2)]:
  - @sveltejs/kit@3.0.0-next.8

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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.

Protect *.server.* files in workspace

2 participants