npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@wc-toolkit/svelte-types

v1.0.3

Published

This package generates Svelte types for custom elements / web components

Readme

workbench with tools, html, css, javascript, and svelte logos

WC Toolkit Custom Element Svelte Types Generator

This package generates TypeScript declarations for custom elements used in Svelte projects. The generated declarations provide type-safe validation for component attributes, component properties, custom events, and CSS custom properties.

Types are generated for all custom elements defined in a Custom Elements Manifest.

Generated declarations include:

  • Custom element names and component descriptions
  • Attributes and their manifest types
  • Component properties passed through Svelte attributes
  • Custom event handlers using Svelte's on: syntax
  • Global element properties and optional DOM event handlers
  • CSS custom properties
  • Documentation for methods, slots, CSS parts, and CSS states

Usage

This package supports three generation workflows:

  1. Calling a function in your build pipeline
  2. Using a plugin for the Custom Element Manifest Analyzer
  3. Using a plugin for @wc-toolkit/cem-generator

Install

npm install --save-dev @wc-toolkit/svelte-types

Build Pipeline

import {
  generateSvelteTypes,
  type SvelteTypesOptions,
} from "@wc-toolkit/svelte-types";
import manifest from "./custom-elements.json";

const options: SvelteTypesOptions = {
  outdir: "./src",
  fileName: "custom-elements-svelte.d.ts",
};

generateSvelteTypes(manifest, options);

CEM Analyzer

Setup

Ensure the following steps have been completed before using the plugin:

Import

// custom-elements-manifest.config.js
import { customElementSveltePlugin } from "@wc-toolkit/svelte-types";

export default {
  plugins: [
    customElementSveltePlugin({
      outdir: "./src",
      fileName: "custom-elements-svelte.d.ts",
    }),
  ],
};

cem-generator Plugin

import { generateCem } from "@wc-toolkit/cem-generator";
import { svelteTypesGeneratorPlugin } from "@wc-toolkit/svelte-types";

generateCem({
  plugins: [svelteTypesGeneratorPlugin({ outdir: "./src" })],
});

Implementation

The generated file declares svelteHTML.IntrinsicElements, so Svelte projects only need to include the file in their TypeScript project.

Option 1: Include the Generated File

Write the generated file somewhere covered by your tsconfig.json:

{
  "include": [
    "src/**/*.ts",
    "src/**/*.svelte",
    "src/custom-elements-svelte.d.ts"
  ]
}

Option 2: Configure TypeScript Types

If the generated declaration is published by a package, add its path to tsconfig.json:

{
  "compilerOptions": {
    "types": ["my-library/custom-elements-svelte"]
  }
}

The generated declarations can then be used directly in Svelte markup:

<x-button
  label="Save"
  value={value}
  on:change={handleChange}
/>

Configuration Options

The SvelteTypesOptions type provides configuration options for the generator.

Output Options

fileName

  • Type: string
  • Default: "custom-elements-svelte.d.ts"
  • Description: Name of the generated declaration file. If omitted or set to undefined, the generator returns the declaration text without writing a file.
{
  fileName: "my-components.d.ts";
}

outdir

  • Type: string
  • Default: "./"
  • Description: Directory where the generated declaration file is written.
{
  outdir: "./src/types";
}

exclude

  • Type: string[]
  • Default: []
  • Description: Component class names to exclude from generation.
{
  exclude: ["InternalComponent", "DeprecatedComponent"];
}

Import Options

componentTypePath

  • Type: (name: string, tag?: string, modulePath?: string) => string
  • Description: Returns the module path used to import each component class. The third argument is the component's source module path from the manifest. When configured, generated attributes reference the imported component class properties.
{
  componentTypePath: (name, tagName) =>
    `my-library/components/${tagName}/${tagName}.js`;
}

The generated declaration expects named component exports:

import type { XButton } from "my-library/components/x-button/x-button.js";

globalTypePath

  • Type: string
  • Description: Imports all component classes and named event detail types from one module instead of generating per-component import paths.
{
  globalTypePath: "my-library/types";
}

When globalTypePath or componentTypePath is not configured, types are read directly from the manifest.

Event Options

globalEvents

  • Type: string
  • Description: Adds custom event declarations to every generated component type.
{
  globalEvents: `
    /** Fired when application telemetry is recorded. */
    "on:telemetry"?: (event: CustomEvent<TelemetryDetail>) => void;
  `;
}

includeDefaultDOMEvents

  • Type: boolean
  • Default: false
  • Description: Adds common DOM event handlers such as on:click, onclick, on:focus, and onfocus to every component. Enable this only when those handlers are useful for your component API.
{
  includeDefaultDOMEvents: true;
}

includeModernEventHandlers

  • Type: boolean
  • Default: true
  • Description: Includes Svelte 5 event attributes such as onclick alongside legacy on: handlers. Set to false when supporting only the legacy event directive syntax.
{
  includeModernEventHandlers: true;
}

Custom events from the manifest are generated using Svelte's legacy event directive syntax and, by default, Svelte 5 event attributes:

<x-button on:change={handleChange} />
<x-button onchange={handleChange} />

For a manifest event typed as CustomEvent<ChangeDetail>, the generated handlers are:

"on:change"?: (e: CustomEvent<ChangeDetail>) => void;
"onchange"?: (e: CustomEvent<ChangeDetail>) => void;

Non-custom event types from the manifest are preserved. For example, an event typed as MouseEvent generates a MouseEvent handler rather than wrapping it in CustomEvent.

Manifest Type Options

typesSrc

  • Type: string
  • Description: Reads types from an alternate property on CEM attributes or properties, such as parsedType. If not provided, the standard type field is used.
{
  typesSrc: "parsedType";
}

This is useful when another CEM plugin adds parsed or transformed type information:

{
  "name": "variant",
  "type": { "text": "ButtonVariant" },
  "parsedType": { "text": "\"primary\" | \"secondary\"" }
}

Tag Formatting

tagFormatter

  • Type: (tagName: string) => string
  • Description: Formats tag names before they are added to CustomElements.
{
  tagFormatter: (tagName) => tagName.replace("my-", "custom-");
}

Utility Options

skip

  • Type: boolean
  • Default: false
  • Description: Prevents generation when true.
{
  skip: process.env.SKIP_TYPES === "true";
}

debug

  • Type: boolean
  • Default: false
  • Description: Enables generator logs.
{
  debug: true;
}

componentDescriptionOptions

  • Type: ComponentDescriptionOptions
  • Description: Configures the component documentation rendered into the generated declaration file, including description source and API order.
{
  componentDescriptionOptions: {
    descriptionSrc: "summary",
    order: ["attrsAndProps", "events", "slots", "methods", "cssProps"]
  }
}

Svelte Features

Component Properties

Public component properties are generated as typed component attributes. This is the valid way to pass values to lowercase custom elements in Svelte:

<x-slider value={value} />

Read-only and static properties are excluded. When a CEM property is associated with an attribute, it is emitted once using the attribute name.

Custom Events

Manifest events are available through on: handlers:

<x-input
  on:change={(event) => {
    console.log(event.detail);
  }}
/>

Named event detail types are imported automatically when the component type path is configured.

CSS Custom Properties

CEM CSS custom properties are generated as Svelte style directives and accept string | number values:

<x-slider style:--track-color={trackColor} />

Svelte applies these values through its CSS custom-property wrapper. The generated declaration includes the property as:

"style:--track-color"?: string | number;

Slots

Slot metadata is included in the generated component documentation. Web component slots are used with Svelte's standard slot attribute:

<x-card>
  <span slot="title">Card title</span>
  Card content
</x-card>

Refs and Methods

The generator exports a *Element type for each component. When component type imports are configured, this aliases the imported class. Otherwise, it includes method signatures found in the manifest. Use it with Svelte's bind:this:

<script lang="ts">
  import type { DialogElement } from "./types/custom-elements-svelte";

  let dialog: DialogElement;

  function openDialog() {
    dialog.showModal();
  }
</script>

<x-dialog bind:this={dialog} />
<button onclick={openDialog}>Open</button>

Named CEM slots also produce a slot-name union for application code:

import type { CardSlots } from "./types/custom-elements-svelte";

const slotName: CardSlots = "header";

Complete Configuration Example

import { generateSvelteTypes } from "@wc-toolkit/svelte-types";
import manifest from "./custom-elements.json";

generateSvelteTypes(manifest, {
  // Output
  fileName: "custom-elements-svelte.d.ts",
  outdir: "./src/types",

  // Component filtering
  exclude: ["InternalComponent"],

  // Type imports
  componentTypePath: (name, tagName) =>
    `my-library/components/${tagName}/${tagName}.js`,

  // Events
  includeDefaultDOMEvents: true,
  globalEvents: `
    "on:telemetry"?: (event: CustomEvent<TelemetryDetail>) => void;
  `,

  // Manifest types and tag names
  typesSrc: "parsedType",
  tagFormatter: (tagName) => tagName.toLowerCase(),

  // Component documentation and development
  componentDescriptionOptions: {
    descriptionSrc: "summary",
  },
  debug: process.env.DEBUG === "true",
  skip: false,
});

For more information about this package and other Web Component tools, visit the WC Toolkit website.