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

sdocs

v0.0.19

Published

A lightweight documentation tool for Svelte 5 components

Readme

sdocs

A lightweight documentation tool for Svelte 5 components. Discover .sdoc files in your project and get an interactive component explorer with live previews, prop controls, and code highlighting.

Quick Start

# Initialize config
npx sdocs init

# Start dev server
npx sdocs dev

Installation

npm install sdocs

Requirements: Svelte 5, Vite 6+, @sveltejs/vite-plugin-svelte 5+

Usage

sdocs can be used in two ways: as a standalone CLI tool or embedded in your existing project.

Standalone (CLI)

Run sdocs as its own dev server:

npx sdocs dev      # Start dev server with HMR
npx sdocs build    # Build static documentation site
npx sdocs preview  # Preview the built site locally
npx sdocs init     # Scaffold a sdocs.config.js file

Embedded in a SvelteKit / Vite Project

Use sdocs as a Vite plugin inside your existing project. This way sdocs runs alongside your app without needing a separate server.

1. Add the Vite plugin

// vite.config.js
import { sveltekit } from '@sveltejs/kit/vite';
import { sdocsPlugin } from 'sdocs/vite';

export default {
  plugins: [
    sveltekit(),
    sdocsPlugin({
      include: ['./src/lib/**/*.sdoc'],
      css: './src/styles/global.css',
      logo: 'My Design System',
    })
  ],
};

The plugin discovers .sdoc files and exposes them via a virtual:sdocs module.

2. Create a page that mounts the sdocs app

<!-- src/routes/docs/+page.svelte -->
<script>
  import App from 'sdocs/client';
  import { docs, cssNames } from 'virtual:sdocs';
</script>

<App
  {docs}
  {cssNames}
  logo="My Design System"
  sidebarConfig={{
    order: { root: ['Components', '*'] },
    open: ['Components'],
  }}
/>

3. Add the virtual module type declaration (optional, for TypeScript)

// src/app.d.ts or any .d.ts file
declare module 'virtual:sdocs' {
  import type { DocEntry } from 'sdocs';
  export const docs: DocEntry[];
  export const cssNames: string[];
  export default docs;
}

That's it — your docs page lives at /docs inside your existing app.

Writing Docs

sdocs supports three types of doc files:

Component Docs (.sdoc)

Document a Svelte component with interactive controls and examples.

<!-- Button.sdoc -->
<script lang="ts">
  import Button from './Button.svelte';

  export const meta = {
    component: Button,
    title: 'Components / Button',
    description: 'A flexible button component.',
    args: {
      label: 'Click me',
      size: 'md',
      disabled: false,
    },
  };
</script>

{#snippet Default()}
  <Button {...args} />
{/snippet}

{#snippet WithIcon()}
  <Button>
    <Icon name="settings" /> Settings
  </Button>
{/snippet}
  • component — the Svelte component to document (auto-extracts props, events, snippets, methods, state, CSS custom properties)
  • title — slash-separated path for sidebar navigation (e.g. 'Components / Button')
  • args — default prop values, used as initial values for interactive controls
  • Default snippet — gets live interactive controls. Auto-generated as <Component {...args} /> if omitted.
  • Named snippets — static examples listed in the sidebar

Page Docs (.page.sdoc)

Freeform content pages with auto-generated table of contents.

<!-- GettingStarted.page.sdoc -->
<script lang="ts">
  export const meta = {
    title: 'Docs / Getting Started',
    description: 'How to set up sdocs.',
  };
</script>

<h1>Getting Started</h1>
<p>Install sdocs and create your first doc file.</p>

<h2>Installation</h2>
<p>Run <code>npm install sdocs</code>...</p>

Table of contents is auto-generated from <h2>, <h3>, and <h4> headings.

Layout Docs (.layout.sdoc)

Component compositions rendered in an isolated iframe.

<!-- LoginForm.layout.sdoc -->
<script lang="ts">
  import Card from './Card.svelte';
  import Input from './Input.svelte';
  import Button from './Button.svelte';

  export const meta = {
    title: 'Patterns / Login Form',
    description: 'A login form combining multiple components.',
    settings: { padding: '24px' },
  };
</script>

<Card padding="24px">
  <Input label="Email" type="email" />
  <Input label="Password" type="password" />
  <Button>Sign in</Button>
</Card>

Prop Extraction

sdocs automatically extracts from your Svelte components:

| What | Source | |------|--------| | Props | $props() destructuring + interface Props {} | | Events | Callback props (onclick, onchange, etc.) | | Snippets | Props typed as Snippet or Snippet<[...]> | | Methods | Exported functions | | State | Exported $state / $derived values | | CSS Custom Properties | var(--name) usages in <style> |

JSDoc comments on props are picked up as descriptions.

Interactive Controls

The Default snippet gets live controls based on prop types:

| Prop Type | Control | |-----------|---------| | string | Text input | | number | Number input | | boolean | Checkbox | | Color (#hex) | Color picker | | Dimension (16px) | Number + unit |

Configuration

Create sdocs.config.js in your project root (or run npx sdocs init):

/** @type {import('sdocs').SdocsConfig} */
export default {
  // Glob pattern(s) to find .sdoc files
  include: ['./src/**/*.sdoc'],

  // Dev server port
  port: 3000,

  // Open browser on start
  open: true,

  // Sidebar logo text
  logo: 'My Design System',

  // CSS loaded in preview iframes
  css: './src/styles/global.css',

  // Sidebar ordering
  sidebar: {
    order: {
      root: ['Components', '*', 'Documentation'],
    },
    open: ['Components'],
  },
};

CSS Stylesheet Switching

Provide named stylesheets to let users switch between them (e.g. light/dark themes):

css: {
  light: './src/styles/light.css',
  dark: './src/styles/dark.css',
}

Sidebar Ordering

Control the order of items in the sidebar with sidebar.order. Use '*' as a wildcard for remaining items in alphabetical order:

sidebar: {
  order: {
    root: ['Getting Started', 'Components', '*'],
    Components: ['Button', 'Input', '*'],
  },
  open: ['Components'],
}

Package Exports

| Export | Description | |--------|-------------| | sdocs | Main entry — sdocsPlugin + types | | sdocs/vite | Vite plugin function | | sdocs/client | App.svelte UI component | | sdocs/ui | Reusable UI components (Button, Frame, Icon, Control, NavTree, Stack) |

License

MIT