Skip to main content

Frequently Asked Questions

How do I use HMR with SvelteKit?

SvelteKit has HMR enabled by default powered by svelte-hmr. If you saw Rich's presentation at the 2020 Svelte Summit, you may have seen a more powerful-looking version of HMR presented. This demo had svelte-hmr's preserveLocalState flag on. This flag is now off by default because it may lead to unexpected behaviour and edge cases. But don't worry, you are still getting HMR with SvelteKit! If you'd like to preserve local state you can use the @hmr:keep or @hmr:keep-all directives as documented on the svelte-hmr page.

How do I include details from package.json in my application?

You cannot directly require JSON files, since SvelteKit expects svelte.config.js to be an ES module. If you'd like to include your application's version number or other information from package.json in your application, you can load JSON like so:

svelte.config.js
ts
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
 
const file = fileURLToPath(new URL('package.json', import.meta.url));
const json = readFileSync(file, 'utf8');
const pkg = JSON.parse(json);

How do I fix the error I'm getting trying to include a package?

Most issues related to including a library are due to incorrect packaging. You can check if a library's packaging is compatible with Node.js by entering it into the publint website.

Here are a few things to keep in mind when checking if a library is packaged correctly:

  • exports takes precedence over the other entry point fields such as main and module. Adding an exports field may not be backwards-compatible as it prevents deep imports.
  • ESM files should end with .mjs unless "type": "module" is set in which any case CommonJS files should end with .cjs.
  • main should be defined if exports is not. It should be either a CommonJS or ESM file and adhere to the previous bullet. If a module field is defined, it should refer to an ESM file.
  • Svelte components should be distributed as uncompiled .svelte files with any JS in the package written as ESM only. Custom script and style languages, like TypeScript and SCSS, should be preprocessed as vanilla JS and CSS respectively. We recommend using svelte-package for packaging Svelte libraries, which will do this for you.

Libraries work best in the browser with Vite when they distribute an ESM version, especially if they are dependencies of a Svelte component library. You may wish to suggest to library authors that they provide an ESM version. However, CommonJS (CJS) dependencies should work as well since, by default, vite-plugin-svelte will ask Vite to pre-bundle them using esbuild to convert them to ESM.

If you are still encountering issues we recommend searching both the Vite issue tracker and the issue tracker of the library in question. Sometimes issues can be worked around by fiddling with the optimizeDeps or ssr config values though we recommend this as only a short-term workaround in favor of fixing the library in question.

How do I use X with SvelteKit?

Make sure you've read the documentation section on integrations. If you're still having trouble, solutions to common issues are listed below.

How do I setup a database?

Put the code to query your database in a server route - don't query the database in .svelte files. You can create a db.js or similar that sets up a connection immediately and makes the client accessible throughout the app as a singleton. You can execute any one-time setup code in hooks.js and import your database helpers into any endpoint that needs them.

How do I use middleware?

adapter-node builds a middleware that you can use with your own server for production mode. In dev, you can add middleware to Vite by using a Vite plugin. For example:

ts
import { sveltekit } from '@sveltejs/kit/vite';
 
/** @type {import('vite').Plugin} */
const myPlugin = {
name: 'log-request-middleware',
configureServer(server) {
server.middlewares.use((req, res, next) => {
console.log(`Got request ${req.url}`);
next();
});
}
};
 
/** @type {import('vite').UserConfig} */
const config = {
plugins: [myPlugin, sveltekit()]
};
 
export default config;

See Vite's configureServer docs for more details including how to control ordering.

How do I use a client-side only library that depends on document or window?

If you need access to the document or window variables or otherwise need code to run only on the client-side you can wrap it in a browser check:

ts
import { browser } from '$app/environment';
 
if (browser) {
// client-only code here
}

You can also run code in onMount if you'd like to run it after the component has been first rendered to the DOM:

ts
import { onMount } from 'svelte';
 
onMount(async () => {
const { method } = await import('some-browser-only-library');
method('hello world');
});

If the library you'd like to use is side-effect free you can also statically import it and it will be tree-shaken out in the server-side build where onMount will be automatically replaced with a no-op:

ts
import { onMount } from 'svelte';
import { method } from 'some-browser-only-library';
 
onMount(() => {
method('hello world');
});

Otherwise, if the library has side effects and you'd still prefer to use static imports, check out vite-plugin-iso-import to support the ?client import suffix. The import will be stripped out in SSR builds. However, note that you will lose the ability to use VS Code Intellisense if you use this method.

ts
import { onMount } from 'svelte';
import { method } from 'some-browser-only-library?client';
 
onMount(() => {
method('hello world');
});

Does it work with Yarn 2?

Sort of. The Plug'n'Play feature, aka 'pnp', is broken (it deviates from the Node module resolution algorithm, and doesn't yet work with native JavaScript modules which SvelteKit — along with an increasing number of packages — uses). You can use nodeLinker: 'node-modules' in your .yarnrc.yml file to disable pnp, but it's probably easier to just use npm or pnpm, which is similarly fast and efficient but without the compatibility headaches.

How do I use with Yarn 3?

Currently ESM Support within the latest Yarn (version 3) is considered experimental.

The below seems to work although your results may vary.

First create a new application:

yarn create svelte myapp
cd myapp

And enable Yarn Berry:

yarn set version berry
yarn install

Yarn 3 global cache

One of the more interesting features of Yarn Berry is the ability to have a single global cache for packages, instead of having multiple copies for each project on the disk. However, setting enableGlobalCache to true causes building to fail, so it is recommended to add the following to the .yarnrc.yml file:

nodeLinker: node-modules

This will cause packages to be downloaded into a local node_modules directory but avoids the above problem and is your best bet for using version 3 of Yarn at this point in time.