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

@payloadpack/theme

v0.2.4

Published

Admin theme for Payload 4: a warm dark palette, a comfortable density and Lucide icons, switchable from the user menu.

Readme

The theme adds three appearance controls to the user menu: a warm dark palette, a roomier density and Lucide icons. Each person picks their own, and the choice is rendered on the server, so pages never flash.

Install

bun add @payloadpack/theme
import { themePlugin } from '@payloadpack/theme'

export default buildConfig({
  plugins: [themePlugin()]
})

Then regenerate the import map:

payload generate:importmap

Appearance

Open the user menu → Appearance:

The plugin renames Payload's Settings submenu in English only, so other languages keep Payload's translation. To rename it in another language, or pick a different name, set general.settings for that language in your own i18n.translations.

| Control | Options | Default | | ------- | -------------------- | ----------- | | Style | Stock, Neutral | Neutral | | Density | Compact, Comfortable | Comfortable | | Icons | Payload, Lucide | Lucide |

  • Neutral gives dark mode a warm near-black palette and swaps Payload's blue selection for neutral greys. In both modes it draws a 2px focus ring in the text color and fills checked checkboxes and selected radios with the text color instead of blue.
  • Comfortable sets 14px body text, 36px fields and buttons, 32px menu items and 18px checkboxes and radios, gives dialogs more room, and fixes Payload components that hard-code their sizes.
  • Lucide replaces Payload's icons with Lucide and adds icons to the nav and the document menu. The icons are bundled, so nothing loads from a CDN.

Stock, Compact and Payload icons together are untouched Payload.

Choices are stored per browser in cookies named after your cookiePrefix, the same way Payload stores its light/dark theme.

Options

themePlugin({
  codeEditorFontSize: 13
})

| Option | Default | Description | | -------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | codeEditorFontSize | 13 | Font size for code editors in Comfortable density. Payload's default is 11. Fields that set admin.editorOptions.fontSize keep their own size. false turns it off. |

Vertical tabs

Give a tabs field the VERTICAL_TABS class to list its tabs in a column beside the fields:

import { VERTICAL_TABS } from '@payloadpack/theme'

const field = {
  type: 'tabs',
  admin: { className: VERTICAL_TABS },
  tabs: [
    { label: 'General', fields: [] },
    { label: 'Advanced', fields: [] }
  ]
}

From 768px wide the tabs stack in a 270px column on the left. Narrower screens keep Payload's horizontal tabs. The layout applies whatever each person picks in Appearance. Payload's tab list moves between tabs with the Left and Right arrow keys, and that doesn't change.

Radio cards

Give a radio field the RADIO_CARDS class to show its options as stacked cards with the radio on the right:

import { RADIO_CARDS } from '@payloadpack/theme'

const field = {
  name: 'plan',
  type: 'radio',
  admin: { className: RADIO_CARDS },
  options: ['plus', 'pro', 'enterprise']
}

A label can also be JSX. Its first element is the title and any element after it is shown as a muted description:

{ value: 'plus', label: <><strong>Plus</strong><span>For individuals and small teams.</span></> }

Nav icons

With Icons set to Lucide, every collection and global in the nav gets an icon. Common names get a matching one automatically: a slug containing page, post, media, user, categor, product, order, form, tag, event or more than 30 other words is recognized. Anything else gets a generic icon.

To choose the icon for your own collection, set --payloadpack-icon on its nav link in your admin stylesheet, for example src/app/(payload)/custom.css. Nav links have the id nav-<slug> for collections and nav-global-<slug> for globals:

#nav-recipes {
  --payloadpack-icon: url('/icons/chef-hat.svg');
}

Any single-color SVG works. It is used as a mask, so it takes the nav's text color. To use a Lucide icon, copy its SVG from lucide.dev into public/icons/.

Customize

The theme's CSS sits in @layer payload, so your own custom.css overrides it without specificity fights.

Each toolbar sizes its buttons from its own token. All but the menu items and sidebar tabs default to Payload's --button-height:

| Token | Controls | | ------------------------------------------- | ---------------------------------------- | | --payloadpack-doc-header-button-height | Title bar with Edit, Versions and API | | --payloadpack-doc-controls-button-height | Status and actions bar of a document | | --payloadpack-list-header-button-height | List title bar and its selection bar | | --payloadpack-list-controls-button-height | List toolbar: Filters, Group by, Columns | | --payloadpack-row-button-height | Array and block rows | | --payloadpack-menu-item-height | Popup menu items, 32px | | --payloadpack-sidebar-tabs-height | Collections and Folders tabs, 38px |

Checkboxes and radios share their size and colors:

| Token | Controls | | ------------------------------------- | ------------------------------------------ | | --payloadpack-toggle-size | Box and circle size in Comfortable density | | --payloadpack-toggle-bg | Unchecked background | | --payloadpack-toggle-bg-hover | Unchecked background on hover | | --payloadpack-toggle-border | Unchecked border | | --payloadpack-toggle-checked-bg | Checked fill | | --payloadpack-toggle-checked-border | Checked border | | --payloadpack-toggle-mark | Tick and dot | | --payloadpack-toggle-ring | Keyboard focus ring |

html {
  --payloadpack-row-button-height: 2.5rem;
}

Requirements

  • Payload 4.0.0-beta.5 or later
  • React 19

License

MIT