Skip to content

What is svebcomponents?

Svelte already allows compiling to custom elements today: set customElement: true and you have a working web component.

That is enough for one component. A library is a different job. You write prop metadata by hand for every attribute, assemble a build pipeline SvelteKit does not provide, ship no types to your consumers, and give up server rendering entirely — because a Svelte custom element wipes its shadow root the moment it upgrades.

svebcomponents is the toolchain for that second job.

Svelte customElement: trueWith svebcomponents
Attribute types, reflectionhand-written <svelte:options customElement={...}>inferred from your $props() types
Packagingassemble your own pipelinepackage.json exports are the config
Types for consumersnone.d.ts plus a custom elements manifest
Server renderingnonedeclarative shadow DOM via Lit’s ElementRenderer
Hydrationshadow root wiped, component re-mountedserver DOM adopted in place
Evaluated twicecustomElements.define throwsidempotent

Svelte needs prop metadata to turn an HTML attribute string into a typed prop. Auto-options reads the types you already wrote and generates it, so value: number is all you write to make value="42" arrive as 42.

SvelteKit packages Svelte components, not custom elements. The build infers entrypoints from your exports field, so declaring where the output goes is the same act as configuring the build.

Every build emits TypeScript declarations and a custom elements manifest, so editors autocomplete your tags and querySelector returns a typed element:

import "my-components";
const el = document.querySelector("simple-component");
el?.count; // number | undefined

This is the part plain Svelte custom elements cannot do at all. Svelte’s generated element attaches a shadow root on upgrade, which per spec clears any declarative shadow root the server delivered, and then mounts from scratch.

svebcomponents renders the shadow root on the server as declarative shadow DOM and adopts it in place in the browser: the nodes survive, styles are reused, and the component is reactive afterwards. It is on by default for every SSR-enabled component.

svebcomponents is a good fit if you write Svelte and want to ship components that non-Svelte applications can use — a design system consumed by several frameworks, embeddable widgets, or anything that outlives one app’s stack.

If your consumers are all Svelte applications, plain Svelte components are simpler and faster; you do not need custom elements. If you have no Svelte in your stack at all, Lit is the more direct choice — svebcomponents’ value is that it lets you keep writing Svelte.