Skip to content

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().

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.

JavaScript prop names remain camel-cased while their HTML attributes are kebab-cased:

Prop nameAttribute name
valuevalue
favoriteNumberfavorite-number
isFeaturedis-featured

This lets component code use normal JavaScript naming while consumers get HTML-shaped markup.

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.

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.

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.