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

pickylibrary

v0.3.0

Published

Accessible, themeable Vue 3 base components. Bring your own icons, style it with CSS variables.

Readme

PickyLibrary

Accessible, themeable Vue 3 base components. No Tailwind required, no icon set bundled, no JavaScript configuration.

Status: pre-alpha. The public API is still moving.

Install

npm i pickylibrary
import 'pickylibrary/style.css';
import { BasePill } from 'pickylibrary';

That's the whole setup. There is no preset to register, no build step to configure, and no content/@source globbing to get right.

Theming

Every visual decision is a CSS custom property in the --picky-* namespace. Override them anywhere in your own CSS:

:root {
    --picky-color-primary-500: #f97316;
    --picky-radius-button: 0.75rem;
}

One accent is enough. Hover, borders and the text variant are mixed from it with color-mix(), so they follow your colour instead of falling back to ours.

The one thing CSS cannot work out is whether text on a filled surface should be black or white. Call applyReadableTextColors() once after setting your accents and it decides for you; skip it and a development build warns, with the ratio it measured.

import { applyReadableTextColors } from 'pickylibrary';

document.documentElement.style.setProperty('--picky-color-primary-500', '#f97316');
applyReadableTextColors();

Your overrides win regardless of stylesheet order — PickyLibrary's own tokens live in a cascade layer, and unlayered CSS always beats layered CSS.

Building a theme by hand is optional: ColorPicky generates a ready-to-paste --picky-* block for you.

Dark mode

Works on the system preference out of the box. To control it yourself, put .dark or .light on any ancestor — .light wins even when the OS asks for dark.

Icons

PickyLibrary ships no icons, so you are free to use any source — an icon library, an SVG folder, or your own components. Register a resolver once:

import { provideIcons } from 'pickylibrary';

// Return a URL, a raw SVG string, or a Vue component. Whatever suits your setup.
provideIcons((code, variant) => `/icons/${variant ?? 'solid'}/${code}.svg`);

Components that don't render icons need no resolver at all.

Server-side rendering

Components render to a string in plain Node with no DOM. One thing to set up: give each request its own toast store, so a notification raised while rendering one visitor's page cannot appear on another's.

import { provideToasts } from 'pickylibrary';

// In the setup of your root component
provideToasts();

In the browser this is optional — without it useToast() falls back to a single shared store, which is what you want on the client.

At most three toasts stay on screen; a fourth pushes the oldest off, preferring to drop a polite one so an urgent message is not displaced by a routine confirmation. Change it, or turn the cap off with 0:

import { createToastStore, provideToasts } from 'pickylibrary';

provideToasts(createToastStore({ limit: 5 }));

Components

BaseButton, BaseInput, BasePasswordInput, BaseCheckbox, BaseSwitch, BaseSelect, BaseModal, BaseAlert, BasePill, BaseIcon, BaseToast and ToastContainer, plus the useToast composable.

Every component that takes a colour takes the same seven: primary, secondary, success, danger, warning, info and gray. BaseButton adds custom for an arbitrary CSS colour, picking readable text for it automatically.

Every component types its slots, so replacing a part — an alert's icon, a select's whole dropdown, a checkbox's tick — is autocompleted rather than guessed.

Props, events, slots and template refs for all twelve are listed in API.md, which is generated from the components themselves.

Example

example/ is a working consumer app: a kitchen sink of every component, with live controls for shadow style, corner radius, accent colour and dark mode. It pulls icons from two sources at once — Lucide components and raw Simple Icons SVG — to show that one resolver covers both.

cd example && npm install && npm run dev

Contributing

npm run verify:all is the full gate: lint, types, unit tests, a build, the example app's own typecheck, and the browser suite. GitHub Actions runs it on every push and pull request. npm run verify is the same without the browser, which is what prepublishOnly uses.

Screenshot comparisons run locally only — the baselines are machine-specific, so on a CI runner they report font rendering rather than anything anyone changed. Use npm run test:browser:update after an intentional visual change.

The behaviour, the styling and the Vue layer are deliberately separate; see ARCHITECTURE.md before adding a component.

Styling

Components render semantic class names and data attributes; the shipped stylesheet decides what they look like. Nothing about their appearance is computed in JavaScript, so you can restyle any part from your own CSS without fighting specificity. See STYLING.md for the full contract.

Browser support

Chrome 111+, Firefox 121+, Safari 16.2+ — the floor set by cascade layers, color-mix() and :has(), which the stylesheet relies on and which cannot be compiled away. Those versions are enforced by the build rather than only documented here.

Releasing

An npm version can never be replaced, only superseded, so the version number is part of the release rather than an afterthought.

  1. Note what changed in CHANGELOG.md, breaking changes first.
  2. Set the version: npm version minor for a breaking change, patch otherwise. In 0.x the minor is what carries breaking changes.
  3. npm publish — prepublishOnly runs verify first.
  4. git push --follow-tags.

npm version writes the tag as well, so do not bump the version by hand unless you intend to tag it yourself.

License

MIT