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.174

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: Node 22+, 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 a static site — every route prerendered to real HTML
npx sdocs preview  # Preview the built site locally
npx sdocs init     # Scaffold a sdocs.config.js file
npx sdocs mcp      # Serve the sdocs MCP server on stdio (authoring tools for agents)

MCP server

sdocs mcp serves an MCP server so agent tooling works against the real parser and extractor instead of guessing at the format. Fourteen tools — ten that read, four that write:

| Read | | |---|---| | validate_sdoc | parse .sdoc text, return diagnostics | | get_authoring_guide | the format reference, whole or by section — also on the web as llms.txt | | get_changelog | this install's changelog, breaking changes first | | list_docs | the project's docs, their routes, notes, todos, glossary terms and component statuses — and the running sdocs version | | search_docs | find a page by any name it goes under, or sweep by note type | | check_docs | compile every stage, validate the site structure, report what breaks | | check_coverage | which components have a [COMPONENT] preview | | resolve_visual_target | a stage's preview-only route, for screenshots | | get_component_api | a component's full extracted API and its @component description | | scaffold_component_doc | a starter doc from a component's extracted props |

| Write | | |---|---| | set_notes | replace a [NOTES] block | | set_status | set a [COMPONENT]'s lifecycle status | | set_todos | replace a [TODO] checklist | | toggle_todo | tick one item |

Each write rewrites the smallest span that will do, so formatting survives, and refuses any path the project's include globs do not match.

Register it as a stdio server in any MCP client — e.g. claude mcp add sdocs -- npx -y sdocs mcp — or, while sdocs dev runs, point a local client at http://localhost:3000/mcp. The VS Code extension registers it with the editor automatically. Built sites carry no MCP endpoint.

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 Explorer from 'sdocs/explorer';
  import { docs, cssNames, pageModules } from 'virtual:sdocs';
</script>

<Explorer {docs} {cssNames} {pageModules} title="My Design System" />

pageModules is not optional: [DOC] and [PAGE] bodies compile to their own components and are loaded through it, so an Explorer mounted without it renders those pages blank with no error.

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

A .sdoc file is <script> at the top, entity blocks in the middle, and an optional <style> at the bottom. Every entity is its own sidebar entry, so one file can hold several.

Component docs — [SHOWCASE]

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

[SHOWCASE title="Components / Button" description="A flexible button component."]

	[COMPONENT component={Button} status="ready" args={{ label: 'Click me', disabled: false }}]
		<Button {...args} />
	[/COMPONENT]

	[EXAMPLE title="With icon"]
		<Button><Icon name="settings" /> Settings</Button>
	[/EXAMPLE]

[/SHOWCASE]
  • [COMPONENT] — a live showcase with interactive controls. component={X} names the previewed component (its props, events, snippets, methods, state, and CSS custom properties are extracted automatically) and args sets the control defaults. status is optional: draft, wip, review, experimental, ready or deprecated, shown as a glyph on the component's tab. Two or more [COMPONENT] blocks share one tab strip and must sit inside a [COMPONENTS] wrapper.
  • [EXAMPLE] — frozen showcases rendered exactly as written, shown below the preview area. Each needs a unique title.
  • title — slash-separated path for sidebar navigation.
  • Blocks are UPPERCASE. [COMPONENT] and [EXAMPLE] are also accepted in lowercase for files written before 0.0.139.

Doc pages — [DOC]

Freeform markdown content with {expression} interpolation and Svelte component islands; code fences are inert. The table of contents is generated from the headings.

[DOC title="Docs / Getting Started"]

	## Installation

	Run `npm install sdocs` and create your first doc file.

[/DOC]

Svelte pages — [PAGE]

A page built in plain Svelte, rendered in the docs app's own context — for landing pages and custom routes. A [PAGE] without a @section/ title prefix routes at the site root and belongs to no sidebar; point the config's home at it for a landing page.

<script lang="ts">
	import { CodeBlock } from 'sdocs/ui';
</script>

[PAGE title="Welcome" contentX="center" maxWidth="880px"]

	<h1>my-library</h1>
	<CodeBlock code="npm install -D my-library" lang="bash" />

[/PAGE]

Patterns — [PATTERNS]

One composition of several components — a user menu, a signup panel — with the states it ships in. A [SHOWCASE] with the prop half switched off: no single component whose API it could extract, so no [COMPONENT], no props panel and no controls. Everything else is the same.

<script lang="ts">
	import Avatar from './Avatar.svelte';
	import Menu from './Menu.svelte';
</script>

[PATTERNS title="Patterns / User Menu" description="Avatar, menu and badge."]

	[EXAMPLE title="Signed out"]
		<Menu>Sign in</Menu>
	[/EXAMPLE]

	[EXAMPLE title="Signed in"]
		<Avatar name="Ada" /> <Menu>Profile · Sign out</Menu>
	[/EXAMPLE]

[/PATTERNS]

Each example gets its own sidebar entry and route. Reach for [SHOWCASE] when one component with an API is the subject, and [LAYOUT] when the composition is a whole page.

Layouts — [LAYOUT]

Full-page component compositions rendered on an isolated stage.

<script lang="ts">
	import Card from './Card.svelte';
	import Input from './Input.svelte';
	import Button from './Button.svelte';
</script>

[LAYOUT title="Patterns / Login Form" padding="24px"]

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

[/LAYOUT]

The full language reference lives at gabilungu.github.io/sdocs/language/overview.

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 | @cssvar annotations (defaults from var() fallbacks) |

JSDoc comments on props are picked up as descriptions.

Interactive Controls

Each preview 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,

  // Header title and logo
  title: 'My Design System',

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

  // Top-bar sections, each with its own sidebar order
  sections: [
    { slug: 'components', title: 'Components', order: ['Button', 'Input'] },
    { slug: 'guides', title: 'Guides' },
  ],
};

Customization Axes

Declare the dimensions your design system varies along, and each gets a control in the top bar:

axes: [
  { id: 'scheme',  label: 'Theme',   values: ['light', 'dark'] },
  { id: 'density', label: 'Density', values: ['airy', 'compact'] },
  { id: 'palette', label: 'Color',   values: ['blue', 'red', 'olive'] },
]

The reader's pick lands on every preview, example and layout as a data- attribute — <html data-scheme="dark" data-density="compact"> — and your own CSS gives it meaning:

[data-scheme="dark"]     { color-scheme: dark; --color-bg: #0f1115; }
[data-density="compact"] { --space-md: 8px; }

sdocs never interprets an axis, so you can declare any dimensions you like. The first value is the default, and picks persist across sessions.

CSS Stylesheet Switching

Provide named stylesheets to let users switch between whole files:

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

Reach for axes instead when variants multiply — three palettes × two densities is six stylesheets to maintain but two axes to declare, and axes compose where file swaps can't.

Sidebar Ordering

Sidebar order is per section, set by that section's order array. Listed items come first, in the order given; everything else follows alphabetically, so there is no wildcard to write:

sections: [
  { slug: 'components', title: 'Components', order: ['Button', 'Input'] },
  { slug: 'guides', title: 'Guides', order: ['Getting Started'] },
]

Entities join a section through their title's @slug/ prefix — title="@components/Forms / Button". An order entry names the route path relative to its section.

Package Exports

| Export | Description | |--------|-------------| | sdocs | Main entry — sdocsPlugin + types | | sdocs/vite | Vite plugin function | | sdocs/explorer | Explorer.svelte UI component | | sdocs/ui | Reusable UI components (Button, Frame, Icon, Control, NavTree, Stack) | | sdocs/language | The sdoc scanner, parser, and Svelte projection | | sdocs/grammar/sdoc.tmLanguage.json | TextMate grammar for editors and highlighters |

License

MIT