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

@povio/css-to-tailwind

v0.2.0

Published

Convert CSS styles in HTML and JSX to Tailwind CSS v4 utilities

Readme

@povio/css-to-tailwind

Convert CSS applied to HTML, JSX, and TSX elements into validated Tailwind CSS v4 utilities.

@povio/css-to-tailwind discovers local stylesheets and inline styles, computes the applicable CSS declarations, and appends equivalent Tailwind classes while preserving existing classes, formatting, comments, and unsupported runtime-dependent styles.

Features

  • Converts .html, .htm, .jsx, and .tsx files.
  • Uses Tailwind CSS v4 defaults or a CSS-first Tailwind entry file.
  • Discovers linked CSS, side-effect imports, inline <style> blocks, and nested local @import rules.
  • Converts safe parts of mixed inline styles while retaining dynamic values such as {{ nav.mark }}.
  • Preserves existing classes and validates generated utilities against Tailwind.
  • Supports atomic in-place replacement or a parallel output tree.
  • Provides both a CLI and a typed ESM/CommonJS library API.

Requirements

  • Node.js 24 or newer for the published CLI and library.
  • Tailwind CSS v4.
  • clsx in transformed JSX projects when a dynamic className requires generated utilities.
  • Bun 1.4 or newer when developing this repository from source.

Installation

Install the CLI globally with Bun:

bun add --global @povio/css-to-tailwind

Or install it in a project as a development dependency:

bun add --dev @povio/css-to-tailwind

You can also run the published package without adding it to a project:

bunx --package @povio/css-to-tailwind css-to-tailwind --help

Quick start

Write converted files to a separate directory while preserving their paths:

css-to-tailwind src/page.html src/components/Card.tsx --output-dir converted

The converted files will be written to:

converted/src/page.html
converted/src/components/Card.tsx

To replace inputs in place, omit --output-dir:

css-to-tailwind src/page.html src/components/Card.tsx

In-place conversion parses every input before writing anything and replaces files atomically. Commit or back up inputs before running it.

CLI reference

css-to-tailwind [options] <inputs...>

| Argument or option | Description | | ------------------------------ | ----------------------------------------------------------------------------------------------------------- | | <inputs...> | One or more .html, .htm, .jsx, or .tsx input files. | | --css <path> | Apply an additional CSS file to every input. Repeat the option to add multiple files. | | --tailwind-css <path> | Use a Tailwind CSS v4 entry file for theme variables, utilities, variants, plugins, prefixes, or @config. | | -o, --output-dir <directory> | Write converted files to a parallel directory tree instead of replacing inputs. | | --include-ds | Include CSS inside _ds directories. These generated design-system bundles are skipped by default. | | --remove-styles | Remove a stylesheet reference only when its complete source converted safely. | | -V, --version | Print the installed package version. | | -h, --help | Print CLI usage and available options. |

Display the built-in help at any time:

css-to-tailwind --help

When installed locally, use:

bunx css-to-tailwind --help

Examples

Apply shared CSS to every input:

css-to-tailwind src/page.html \
  --css src/styles/reset.css \
  --css src/styles/components.css

Use a CSS-first Tailwind theme and preserve the source tree:

css-to-tailwind src/page.html src/Card.tsx \
  --tailwind-css src/styles/tailwind.css \
  --output-dir converted

Include a generated _ds stylesheet that would otherwise be skipped:

css-to-tailwind src/page.html --include-ds

Remove only fully converted stylesheet references:

css-to-tailwind src/page.html --remove-styles

CSS discovery

For HTML, the CLI loads:

  • Inline <style> blocks.
  • Local <link rel="stylesheet"> references.
  • CSS passed through repeatable --css options.
  • Nested local CSS @import dependencies.

For JSX and TSX, it loads relative side-effect imports such as:

import "./card.css";

Remote stylesheets and CSS Modules are skipped. CSS files inside a directory named _ds are also skipped by default because they commonly contain the compiled Tailwind utilities being targeted rather than source styles to convert. Use --include-ds to include them.

--tailwind-css is never affected by the _ds exclusion because it configures the target Tailwind design system rather than supplying styles to convert.

Source CSS files are never rewritten or deleted. With --output-dir, discovered CSS dependencies are copied unchanged into the equivalent output tree. Unrelated HTML assets and files referenced through CSS url() declarations are not copied.

Tailwind CSS v4 configuration

Without --tailwind-css, conversion uses Tailwind v4 defaults through an implicit entry:

@import "tailwindcss";

Pass a Tailwind CSS entry to use project-specific theme variables, breakpoints, custom utilities, variants, plugins, prefixes, or a legacy @config directive:

@import "tailwindcss";

@theme {
  --color-brand: #315cf5;
  --breakpoint-wide: 90rem;
}
css-to-tailwind src/page.html --tailwind-css src/styles/tailwind.css

The entry is used only for utility selection and validation. It is not generated or rewritten.

HTML and inline styles

Existing classes are preserved and generated utilities are appended:

<!-- Before -->
<div class="card" style="display: grid; gap: 4px">Hello</div>

<!-- After -->
<div class="card grid gap-1">Hello</div>

Runtime-dependent declarations remain inline while safe siblings convert:

<!-- Before -->
<span style="width:3px;height:16px;background:{{ nav.mark }}"></span>

<!-- After -->
<span style="background:{{ nav.mark }}" class="w-[0.1875rem] h-4"></span>

JSX and TSX

Static classes are preserved. When applicable styles are statically known but className is dynamic, the converter rewrites it through clsx:

// Before
<button className={active ? "active" : undefined} />

// After
<button className={clsx(active ? "active" : undefined, "rounded-md px-4")} />

An existing clsx import is reused. Otherwise, a collision-safe import is added and a CLSX_REQUIRED diagnostic is returned. The transformed project must have clsx installed:

bun add clsx

Static properties in style={{ ... }} are converted. Spreads, unsupported properties, and dynamic values remain in the style object.

Library API

The package exposes ESM and CommonJS builds with TypeScript declarations.

Convert source in memory

import { createConverter } from "@povio/css-to-tailwind";

const converter = await createConverter({
  tailwindCss: {
    filename: "/project/src/tailwind.css",
    code: '@import "tailwindcss"; @theme { --color-brand: #315cf5; }',
  },
});

const result = await converter.convert({
  filename: "/project/src/card.html",
  code: '<div class="card" style="color: #315cf5">Hello</div>',
  cssSources: [
    {
      filename: "/project/src/card.css",
      code: ".card { padding: 1rem; }",
      origin: "explicit",
    },
  ],
  removeStyles: false,
});

console.log(result.code);
console.log(result.generatedClasses);
console.log(result.dependencies);
console.log(result.diagnostics);

Convert files

convertFiles performs discovery and is the only public API that writes to the filesystem:

import { convertFiles } from "@povio/css-to-tailwind";

const results = await convertFiles({
  inputs: ["src/page.html", "src/Card.tsx"],
  cssPaths: ["src/styles/global.css"],
  tailwindCssPath: "src/styles/tailwind.css",
  outputDir: "converted",
  removeStyles: false,
  includeDesignSystemCss: false,
  cwd: process.cwd(),
});

The package exports ConversionResult, FileConversionResult, CssSource, Diagnostic, and all converter option types.

Diagnostics and exit codes

Warnings include a code, source filename, and line/column when available. They report skipped selectors, unsupported at-rules, remote stylesheets, CSS Modules, retained stylesheet references, required clsx installation, and assets that are not copied.

  • Exit 0: conversion completed, including conversions with warnings.
  • Exit 1: invalid arguments, unsupported inputs, fatal template parsing, unsafe paths, Tailwind configuration failures, or filesystem errors.

Known limitations

  • Input templates are limited to .html, .htm, .jsx, and .tsx.
  • CSS Modules, Vue, Svelte, runtime-rendered DOM, and remote stylesheets are not evaluated.
  • Selectors depending on runtime-only classes or unresolved JSX component output are retained.
  • Output-directory mode does not copy unrelated HTML assets or files referenced through CSS url() declarations.
  • Stylesheet removal is deliberately conservative; unmatched or unsupported rules keep their original reference.

Development

Install dependencies:

bun install

Run the CLI directly from TypeScript:

bun run cli --help
bun run cli src/page.html --output-dir converted

Run the project checks:

bun test
bun run lint
bun run typecheck
bun run format:check
bun run build

The production build is written to dist/ and contains the executable CLI, ESM/CommonJS library bundles, source maps, and type declarations.