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

paintoliver

v0.1.1

Published

Apply consistent visual vibes to front-end codebases — safely, predictably, and at scale.

Readme

Paintoliver

Apply consistent visual vibes to front-end codebases — safely, predictably, and in seconds.

FrontEnd Agent transforms the visual styling of an existing project to match a selected design "vibe" — without touching business logic, component structure, or application behavior.


Install

npm install -g paintoliver

Quick Start

# See what's available
paintoliver list

# Preview changes without writing anything (always a good first step)
paintoliver apply minimal ./your-project --dry-run

# Apply a vibe
paintoliver apply kinetic-terminal ./your-project

# Didn't like it? Restore the backup that was created automatically
paintoliver restore ./your-project

What is a Vibe?

A vibe is a fully portable definition of a visual language: colors, typography, spacing, border radius, shadows, and motion — structured as data, not instructions. Every vibe ships with both light and dark mode variants. The same vibe applied to the same project always produces the same result.

Built-in vibes:

| Vibe | Character | Base mode | |---|---|---| | kinetic-terminal | High-contrast cyberpunk. Cyan/magenta on near-black. Neon glow. | Dark | | minimal | Maximum whitespace. Barely-there borders. Swiss typography. | Light | | brutalist | Black borders. Heavy type. Zero decoration. Raw structure. | Light | | corporate | Electric blue. Precise grid. Trustworthy and legible. | Light | | glassmorphism | Frosted glass surfaces. Violet gradients. Translucent layers. | Dark | | windows-xp | Skeuomorphic chrome. Gradients and bevels. Warm cream surfaces. | Light |


Commands

apply

paintoliver apply <vibe> [path]
paintoliver apply [path]            # prompts for vibe if omitted

| Flag | Default | Description | |---|---|---| | --dry-run | off | Preview all changes without writing any files | | --backup | on | Create a timestamped backup before modifying | | --no-backup | — | Skip backup creation | | --watch | off | Re-apply automatically when CSS files change | | --fix-contrast | off | Auto-fix any WCAG AA contrast failures | | --no-contrast | off | Skip contrast checking entirely | | --fonts | off | Inject a Google Fonts @import for the vibe's typefaces | | --verbose | off | Show before/after values for every change | | --report <path> | — | Write a machine-readable JSON report |

analyze

paintoliver analyze [path]
paintoliver analyze [path] --json

Scans a project and reports its styling system, detected CSS variables, entry points, and theme mode. Read-only — no files are modified.

list

paintoliver list

Lists all available vibes with descriptions and tags.

list-backups

paintoliver list-backups [path]

Shows all backups for a project with timestamps and ages.

restore

paintoliver restore [path]
paintoliver restore [path] --backup-id 2026-04-08T12-00-00

Restores files from the most recent backup, or a specific one by ID.

clear-overrides

paintoliver clear-overrides [path]

Removes any persisted contrast overrides from .paintoliver.json, reverting to the vibe's original colors on the next apply.


How It Works

1. Analyze

Scans the project to detect the styling system (Tailwind v3/v4, CSS modules, SCSS, plain CSS), find CSS entry points, extract custom property names, and detect the project's theme mode.

2. Backup

Copies every file that will be modified into .paintoliver-backup/<timestamp>/ before any writes happen.

3. Transform

  • Tailwind projects — updates tailwind.config.js color/font/radius sections or injects a @theme block (v4)
  • CSS/SCSS files — rewrites custom property values that map to semantic vibe tokens, correctly handling separate dark-mode and light-mode selector blocks
  • Token-less projects — injects a complete token block into the primary CSS entry point, including base, @media (prefers-color-scheme), and .dark/.light class selector blocks

4. Contrast check

After transformation, runs WCAG 2.2 AA checks on the applied palette (4.5:1 for text, 3.0:1 for UI components). Failures can be auto-fixed or reviewed interactively. Fixes are saved to .paintoliver.json and reapplied on every subsequent run.

5. Report

Every change is printed with a confidence indicator. Low-confidence rewrites are flagged for review. A full JSON report can be written for code review.


Safety

  • Backups by default — a timestamped copy of all modified files is saved before any writes
  • Dry run mode — preview every change before it happens
  • Confidence scoring — CSS variables that can't be confidently mapped to a semantic token are left untouched
  • No deletions — no files, variables, or classes are ever removed
  • Fails safely — files that can't be processed confidently are skipped and reported, not errored

Dark and Light Mode

Every vibe defines a base mode and an override for the opposite mode. When a token block is injected into a project, three blocks are written:

/* Base (default mode) */
:root { --primary: #00F0FF; ... }

/* System preference */
@media (prefers-color-scheme: light) {
  :root:not(.dark):not([data-theme="dark"]) { --primary: #008A96; ... }
}

/* Explicit class (Next.js next-themes, Tailwind darkMode: 'class', etc.) */
.light, [data-theme="light"] { --primary: #008A96; ... }

Only tokens that differ between modes are listed in the override blocks — everything else inherits from :root.


Watch Mode

paintoliver apply kinetic-terminal ./your-app --watch

Watches for changes to CSS and config files and re-applies the vibe automatically with a 350ms debounce. Useful during active design iteration. No backup is created on re-applies.


Adding a Custom Vibe

  1. Create src/vibes/definitions/my-vibe.ts exporting a Vibe object
  2. Add its ID to the VibeId union in src/vibes/types.ts
  3. Import and register it in src/vibes/registry.ts

That's it. The CLI, analyzer, transformer, and reporter pick it up automatically.

Refer to any existing vibe in src/vibes/definitions/ as a template, and src/vibes/types.ts for the full interface.


Supported Projects

| Stack | Support | |---|---| | React + Tailwind v4 | Full | | React + Tailwind v3 | Full | | React + CSS Modules | CSS custom properties | | React + plain CSS/SCSS | CSS custom properties | | Next.js | Full (same as React above) | | Vue / Svelte | CSS-level transforms only | | styled-components / Emotion | CSS custom properties only |


Requirements

  • Node.js ≥ 18