Skip to content

Getting Started

svebcomponents can be retrofitted onto any project. The starter template is the quickest way to get everything set up.

Clone the starter template without Git history with degit:

Terminal window
pnpm dlx degit svebcomponents/template my-component-library

Install its dependencies:

Terminal window
cd my-component-library
pnpm install

Create the component package inside the template’s components workspace:

Terminal window
mkdir -p components/cool-counter/src
cd components/cool-counter

Add package.json:

{
"name": "cool-counter",
"version": "0.0.1",
"type": "module",
"files": ["dist", "custom-elements.json"],
"customElements": "custom-elements.json",
"scripts": {
"build": "svebcomponents",
"dev": "vite"
},
"exports": {
".": {
"types": "./dist/client/CoolCounter.d.ts",
"default": "./dist/client/CoolCounter.js"
},
"./svelte": {
"types": "./dist/client/CoolCounter.svelte-types.d.ts"
}
},
"devDependencies": {
"@svebcomponents/build": "^0.6.0",
"svelte": "^5.0.0",
"vite": "^8.0.0"
}
}

svebcomponents maps an export such as ./dist/client/CoolCounter.js to src/CoolCounter.svelte.

Create src/CoolCounter.svelte:

<svelte:options customElement="cool-counter" />
<script lang="ts">
let { increments = 1 }: { increments?: number } = $props();
let count = $state(0);
</script>
<button onclick={() => (count += increments)}>
add {increments} to {count}
</button>

<svelte:options> is only used to declare the tag name. Attribute types are inferred automatically.

Terminal window
pnpm install
pnpm build

This invokes the svebcomponents CLI, which reads the $props() type and supplies the metadata Svelte’s custom element wrapper uses to convert increments="5" to a number. The build produces the browser bundle and declarations at dist/client. It also writes custom-elements.json at the package root.

The bundle can be distributed as a package on npm. Consumers only need to import "cool-counter"; the element is registered as a side effect and becomes available in the DOM, including through document.createElement("cool-counter").

With the svebcomponents template, add the package as a dependency in apps/svelte-kit/package.json to preview what consumers get:

"dependencies": {
"cool-counter": "workspace:*"
}

Then use it in the app:

<script lang="ts">
import "cool-counter";
</script>
<cool-counter increments={5}></cool-counter>

Return to the template root, install the new workspace dependency, and start the development server:

Terminal window
cd ../..
pnpm install
pnpm dev

Open the local URL printed in the terminal and check out your web component!