Skip to content

Authoring components

Write a Svelte component and declare its custom-element tag. Svelte defines the component behavior; svebcomponents reads the source to generate attribute options, element types, and a custom elements manifest.

Read the Svelte custom elements guide for the compiler rules behind these components.

Give each published component a literal tag name:

<svelte:options customElement="favorite-number" />

svebcomponents uses this string in the generated types and manifest. It cannot name a computed tag during the build.

Declare typed props with Svelte’s $props() rune:

<script lang="ts">
interface Props {
/** Number of items shown on each page. */
pageSize: number;
featured?: boolean;
}
let { pageSize, featured = false }: Props = $props();
</script>

Svelte exposes each prop as a property on the custom element. @svebcomponents/auto-options derives its attribute name, converter, and reflection setting from the TypeScript declaration.

PropertyAttribute
pageSizepage-size
featuredfeatured

Scalar props reflect to attributes. auto-options disables reflection for arrays, objects, and unresolved type references. Read Attribute metadata for the inference rules and overrides.

Dispatch events from Svelte’s $host() rune. Add an explicit type argument when the event carries detail:

<script lang="ts">
interface ChangeDetail {
value: string;
}
function change(value: string) {
$host().dispatchEvent(
new CustomEvent<ChangeDetail>("change", { detail: { value } }),
);
}
</script>

svebcomponents records the literal event name and the CustomEvent type argument. It cannot derive a name from a variable or a detail type from the value passed to detail.

Use <slot> for light DOM content:

<div class="card">
<slot name="header"></slot>
<slot></slot>
</div>
<my-card>
<h2 slot="header">Title</h2>
<p>Body</p>
</my-card>

svebcomponents records static slot names. Read Hydration before you server-render a component with slots.

Svelte puts component styles in the shadow root. Use :host for the custom element and CSS custom properties for values consumers can set:

<style>
:host {
display: inline-block;
border-radius: var(--card-radius, 4px);
}
</style>

svebcomponents records CSS custom properties that the component reads through var() and does not declare in the same stylesheet.

Document props with JSDoc as shown above. Use an @component comment for the component, slots, events, and CSS custom properties:

<!-- @component
A button with a configurable corner radius.
@slot - Button label.
@event change - Fired after the value changes.
@cssprop --button-radius - Corner radius.
-->

The analyzer uses these source patterns for generated types and manifest data:

Source patternGenerated data
Literal <svelte:options> tagCustom-element name
Typed $props() declaration and JSDocProperties, attributes, comments
Literal event name in $host().dispatchEvent(...)Event name and detail type
Static <slot> elementSlot name
External var(--name) in component CSSCSS custom property
@component documentation tagsAPI descriptions