Getting Started
svebcomponents can be retrofitted onto any project. The
starter template is the quickest
way to get everything set up.
Start from the template
Section titled “Start from the template”Clone the starter template without Git history with degit:
pnpm dlx degit svebcomponents/template my-component-libraryInstall its dependencies:
cd my-component-librarypnpm installCreate the package
Section titled “Create the package”Create the component package inside the template’s components workspace:
mkdir -p components/cool-counter/srccd components/cool-counterAdd 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.
Write the component
Section titled “Write the component”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.
Build it
Section titled “Build it”pnpm installpnpm buildThis 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.
Use it
Section titled “Use it”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:
cd ../..pnpm installpnpm devOpen the local URL printed in the terminal and check out your web component!