Packaging
Edit this page on GitHub
svelte-package
is currently experimental. Non-backward compatible changes may occur in any future release.
You can use SvelteKit to build apps as well as component libraries, using the @sveltejs/package
package (npm create svelte
has an option to set this up for you).
When you're creating an app, the contents of src/routes
is the public-facing stuff; src/lib
contains your app's internal library.
A component library has the exact same structure as a SvelteKit app, except that src/lib
is the public-facing bit. src/routes
might be a documentation or demo site that accompanies the library, or it might just be a sandbox you use during development.
Running the svelte-package
command from @sveltejs/package
will take the contents of src/lib
and generate a package
directory (which can be configured) containing the following:
- All the files in
src/lib
, unless you configure custominclude
/exclude
options. Svelte components will be preprocessed, TypeScript files will be transpiled to JavaScript. - Type definitions (
d.ts
files) which are generated for Svelte, JavaScript and TypeScript files. You need to installtypescript >= 4.0.0
for this. Type definitions are placed next to their implementation, hand-writtend.ts
files are copied over as is. You can disable generation, but we strongly recommend against it — people using your library might use TypeScript, for which they require these type definition files. - A
package.json
copied from the project root with all fields except"scripts"
,"publishConfig.directory"
and"publishConfig.linkDirectory"
. The"dependencies"
field is included, which means you should add packages that you only need for your documentation or demo site to"devDependencies"
. A"type": "module"
and an"exports"
field will be added if it's not defined in the original file.
The "exports"
field contains the package's entry points. By default, all files in src/lib
will be treated as an entry point unless they start with (or live in a directory that starts with) an underscore, but you can configure this behaviour. If you have a src/lib/index.js
or src/lib/index.svelte
file, it will be treated as the package root.
For example, if you had a src/lib/Foo.svelte
component and a src/lib/index.js
module that re-exported it, a consumer of your library could do either of the following:
ts
import {Foo } from 'your-library';
ts
importFoo from 'your-library/Foo.svelte';
You should avoid using SvelteKit-specific modules like
$app
in your packages unless you intend for them to only be consumable by other SvelteKit projects. E.g. rather than usingimport { browser } from '$app/environment'
you could useimport.meta.env.SSR
to make the library available to all Vite-based projects or better yet use Node conditional exports to make it work for all bundlers. You may also wish to pass in things like the current URL or a navigation action as a prop rather than relying directly on$app/stores
,$app/navigation
, etc. Writing your app in this more generic fashion will also make it easier to setup tools for testing, UI demos and so on.
Source mapspermalink
You can create so-called declaration maps (d.ts.map
files) by setting "declarationMap": true
in your tsconfig.json
. This will allow editors such as VS Code to go to the original .ts
or .svelte
file when using features like Go to Definition. This means you also need to publish your source files alongside your dist folder in a way that the relative path inside the declaration files leads to a file on disk.
Optionspermalink
svelte-package
accepts the following options:
-w
/--watch
— watch files insrc/lib
for changes and rebuild the package
Publishingpermalink
To publish the generated package:
npm publish ./package
The ./package
above is referring to the directory name generated, change accordingly if you configure a custom package.dir
.
Caveatspermalink
All relative file imports need to be fully specified, adhering to Node's ESM algorithm. This means you cannot import the file src/lib/something/index.js
like import { something } from './something
, instead you need to import it like this: import { something } from './something/index.js
. If you are using TypeScript, you need to import .ts
files the same way, but using a .js
file ending, not a .ts
file ending (this isn't under our control, the TypeScript team has made that decision). Setting "moduleResolution": "NodeNext"
in your tsconfig.json
or jsconfig.json
will help you with this.
This is a relatively experimental feature and is not yet fully implemented. All files except Svelte files (preprocessed) and TypeScript files (transpiled to JavaScript) are copied across as-is.