Auto-options
HTML attributes are strings. Svelte props can be strings, numbers, booleans, arrays, or objects. Custom element prop metadata is what connects those two worlds.
@svebcomponents/auto-options generates that metadata from the TypeScript
types you already write in $props().
Props Are the Source of Truth
Section titled “Props Are the Source of Truth”In Svelte 5, props usually live in $props():
<script lang="ts"> interface Props { label: string; value: number; }
let { label, value }: Props = $props();</script>Before the Svelte compiler runs, auto-options reads this declaration and
generates the equivalent custom element options:
<svelte:options customElement={{ props: { label: { attribute: "label", reflect: true, type: "String" }, value: { attribute: "value", reflect: true, type: "Number" }, }, }}/>When you build with @svebcomponents/build, this transform is already part of
the pipeline.
Attribute Names
Section titled “Attribute Names”JavaScript prop names remain camel-cased while their HTML attributes are kebab-cased:
| Prop name | Attribute name |
|---|---|
value | value |
favoriteNumber | favorite-number |
isFeatured | is-featured |
This lets component code use normal JavaScript naming while consumers get HTML-shaped markup.
Attribute Conversion
Section titled “Attribute Conversion”With generated metadata, Svelte can convert incoming attributes to the corresponding prop types:
<favorite-number value="42" featured="true"></favorite-number>Here, value can become a number and featured can become a boolean instead
of both remaining strings.
Svelte Consumers and Non-string Values
Section titled “Svelte Consumers and Non-string Values”There is one interop detail worth keeping close at hand.
When a Svelte app consumes a custom element, pass non-string values as JavaScript expressions:
<favorite-number value={42}></favorite-number>This passes the number 42.
<favorite-number value="42"></favorite-number>Under certain conditions, Svelte assigns this value directly to the
JavaScript property. In that case the value is the string "42" and the
custom element’s attribute converter is bypassed.
Manual Overrides
Section titled “Manual Overrides”Inference should remove boilerplate without removing control. You can provide custom element prop options manually when you need a different attribute name, type, or reflection behavior:
<svelte:options customElement={{ props: { value: { type: "Number", attribute: "data-value", reflect: false }, }, }}/>auto-options preserves fields you wrote manually and fills in missing props
and fields where it can.
For supported prop shapes, inferred types, standalone plugin setup, and
current limitations, see the
@svebcomponents/auto-options reference.