Using Svelte
Easily use Panda with Svelte with our dedicated integration.
This guide will show you how to set up Panda CSS in a Svelte project using the @pandacss/vite plugin.
Prefer PostCSS? Run panda init --postcss instead of the plugin step below and follow
Using PostCSS. Everything else on this page stays the same.
Start a new project
Create Svelte project
To get started, we will need to create a new Svelte project.
You will be asked a few questions, answer them as follows:
┌ Welcome to SvelteKit!
│
◇ Which Svelte app template?
│ Skeleton project
│
◇ Add type checking with TypeScript?
│ Yes, using TypeScript syntax
│
◇ Select additional options (use arrow keys/space bar)
│ ◼ Add ESLint for code linting
│ ◼ Add Prettier for code formatting
│ ◻ Add Playwright for browser testing
│ ◻ Add Vitest for unit testing
│
└ Your project is ready!Enter the newly created directory and install the dependencies.
Install Panda
Install panda, the Vite plugin, and create your panda.config.ts file:
Add the Vite plugin
Add pandacss() to your Vite plugins. It generates the styled-system folder, injects the CSS, and keeps both up
to date on save. No separate watcher needed.
vite.config.ts
import { defineConfig } from 'vite'
import pandacss from '@pandacss/vite'
import { sveltekit } from '@sveltejs/kit/vite'
export default defineConfig({
plugins: [sveltekit(), pandacss()],
server: {
fs: {
allow: ['styled-system']
}
}
})server.fs.allow lets SvelteKit's dev server read the generated styled-system folder.
Update package.json scripts
Open your package.json file and update the scripts section as follows:
{
"scripts": {
"prepare": "panda codegen",
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
}
}The plugin only runs with Vite. The "prepare" script covers type checking and your editor, which read
styled-system before Vite starts, and lets the folder stay gitignored.
Configure the content
Make sure that all of the paths of your Svelte components are included in the include section of the panda.config.ts
file.
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
// Whether to use css reset
preflight: true,
// Where to look for your css declarations
include: ['./src/**/*.{js,ts,svelte}'],
// Files to exclude
exclude: [],
// The output directory for your css system
outdir: 'styled-system'
})Update Svelte config
Add the styled-system alias to your svelte.config.js file:
svelte.config.js
import adapter from '@sveltejs/adapter-auto'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
/** @type {import('@sveltejs/kit').Config} */
const config = {
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
// for more information about preprocessors
preprocess: [vitePreprocess()],
kit: {
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
// See https://kit.svelte.dev/docs/adapters for more information about adapters.
adapter: adapter(),
alias: {
'styled-system': './styled-system/*'
}
}
}
export default configConfigure CSS layers
Create an src/app.css file with the layer order, and import it from the root layout:
src/app.css
@layer reset, base, tokens, recipes, utilities;src/routes/+layout.svelte
<script>
import '../app.css'
</script>
<slot />The CSS file only sets the layer order. The plugin injects the generated CSS for you.
Start your build process
Run the following command to start your development server.
Start using Panda
Now you can start using Panda CSS in your project. Here is the snippet of code that you can use in your
src/routes/+page.svelte file.
src/routes/+page.svelte
<script>
import { css } from 'styled-system/css'
</script>
<div class={css({ fontSize: '2xl', fontWeight: 'bold' })}>
Hello 🐼!
</div>Optional: drop the styling runtime
By default css() resolves class strings in the browser with a small runtime. Turn on source transforms and the
plugin rewrites static calls to plain class strings at build time, so the runtime never ships:
vite.config.ts
plugins: [sveltekit(), pandacss({ transform: true })]Dynamic values keep their runtime form. See Source transforms.
Troubleshooting
Storybook can't load styled-system files
Storybook runs its own Vite server, which does not inherit the server.fs.allow setting from your vite.config.ts.
Add it in your .storybook folder's main.js (or vite.config.js in older Storybook versions):
main.js
import { defineConfig, mergeConfig } from 'vite'
/** @type { import('@storybook/sveltekit').StorybookConfig } */
const config = {
// other Storybook config...
viteFinal: async config => {
return mergeConfig(
config,
defineConfig({
server: {
fs: {
allow: ['styled-system']
}
}
})
)
}
}
export default configAutocomplete not working
If you're not getting import autocomplete in your IDE, you may need to include the styled-system directory in your
TypeScript config. However, in Svelte your main tsconfig.json file is extending the autogenerated one. To extend it
without overriding the defaults adjust your svelte.config.js to include following entry:
svelte.config.js
import adapter from '@sveltejs/adapter-auto'
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'
/** @type {import('@sveltejs/kit').Config} */
const config = {
// ...
kit: {
// ...
typescript: {
config: config => {
config.include.push('../styled-system')
return config
}
}
}
}
export default config