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

talenote

v1.3.0

Published

![TaleNote](./logo.svg)

Downloads

8

Readme

TaleNote

TaleNote

Storybook-esque component directory, embed right into SvelteKit

Please give it a try, but setting up is a PITA right now. It also only supports SvelteKit from ^1.0.0-next.250

Setting up Storybooks with SvelteKit is a daunting task that's overkill for static / content-focused websites.

TaleNote doesn't run a separate server — instead, it is embedded into SvelteKit's routes directory directly & relies on Vite's glob import to access other components.

demo

Features

  • List all components from a directory or more
  • View a component at different, customizable breakpoints
  • Saving snapshots of props as 'tales'

Setting up

Install talenote:

npm install talenote

In routes, create the following structure:

routes
  └─ talenote
        ├─ __layout.reset.svelte
        ├─ _tales.json
        ├─ component.svelte
        ├─ index.svelte
        └─ tales.js

Directory & filenames are currently hardcoded. There's an example of what these files look like here

__layout.reset.svelte

Just to reset the parent layout, if any.

<slot />

_tales.json

This is where all the props snapshots will be stored. For starter, just leave this in:

{}

I'm 90% confident that lowdb would just create one if there's none, please let me know if it doesn't.

component.svelte

Talenote will mount a Svelte component into this page & load it into an iframe. This is the place to pass in components & any wrapper components.

<script context="module">
	// Write a glob to get your handsome components here. Are they in `lib`? or maybe `components`?
	const modules = import.meta.globEager('/src/lib/**/*.svelte');
</script>

<script>
	import { DisplayComponent } from 'talenote';
</script>

<DisplayComponent {modules} />

index.svelte

This is where Talenote UI lives.

<script lang="ts">
	import { TaleNote } from 'talenote';

	// not required, just something to get the component name instead of the full file path
	const getComponentName = (name: string) => name.split('/src/lib/')[1].split('.svelte')[0];
</script>

<TaleNote {getComponentName} />

tales.js (or .ts)

Talenote uses lowdb to write snapshots of your component props into a local json file. This file exports the required HTTP operations.

import path from 'path';
import { createAPI } from 'talenote';

// __dirname is not a thing with ESM, emulates it with import.meta.url
const taleDir = path.join(import.meta.url, '..').replace('file:', '');
const pathToJson = path.join(taleDir, '_tales.json');
const { post, get, del } = createAPI({ pathToJson });

export { post, get, del };

Note: I always run into strange ESM errors after launching /talenote for the first time. Hard refresh and / or reinstalling node_modules a few times usually fixes them... let me know if you have an idea how to improve this.

Configurations

Set default props

Because Talenote doesn't run any static code analysis, the only way to recognize a component's default props is to export them from that component.

<script context="module">
	export const defaultProps = { name: 'Eri' };
</script>

<script>
	export let name = defaultProps.name;
</script>

<h1>Hello {name}</h1>

Configure wrapper components

When viewing small components such as a button, it's helpful to have them centered on the screen. From within a component, export a taleWrapper with the id of the wrapper. Valid defaults are center and none.

<script context="module">
	export const defaultProps = { name: 'Eri' };

	// center this component
	export const taleWrapper = 'center';

	// alternatively, dont use any wrapper
	export const taleWrapper = 'none';
</script>

<script>
	export let name = defaultProps.name;
</script>

<h1>Hello {name}</h1>

Additional wrappers can be passed into talenote/component.svelte:

<script context="module">
	const modules = import.meta.globEager('/src/components/**/*.svelte');
</script>

<script>
	import { DisplayComponent } from 'talenote';
	import CustomWrapper from './_CustomWrapper.svelte';

	const wrappers = {
		custom: CustomWrapper,

		// set the component above as the default for all components
		default: 'custom'
	};
</script>

// talenote/component.svelte
<DisplayComponent {modules} {wrappers} />

Exclude Talenote from production builds

Starting from 1.0.0-next.249, kit.routes is available in svelte.config.js to filter out unwanted paths.

// svelte.config.js
const config = {
	// Consult https://github.com/sveltejs/svelte-preprocess
	// for more information about preprocessors
	preprocess: preprocess(),

	kit: {
		adapter: adapter(),
		target: '#svelte',
		routes: (filepath) => {
			return process.env.NODE_ENV === 'production' ? !filepath.includes('talenote') : true;
		}
	}
};

Caveats

  • Because component props are serialized & passed back & forth via window.postMessage, functions props are excluded.

  • Tales (component props snapshot) can only be viewed locally, though the component directory can still be shipped.

Contributions

Ideas, PRs, contributions, forks are all welcomed! Built by dereknguyen