MCPcopy Index your code
hub / github.com/TheDecipherist/classpresso

github.com/TheDecipherist/classpresso @v1.7.3

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.7.3 ↗ · + Follow
184 symbols 514 edges 39 files 39 documented · 21%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

classpresso.com

Classpresso

Make utility-first CSS render faster — 50% faster style recalculation, 42% faster First Paint

Classpresso consolidates repeated utility class patterns at build time, dramatically reducing browser rendering work. Works with Tailwind, Bootstrap, Bulma, Tachyons, UnoCSS, and any utility-first CSS framework.

📦 Post-Build Tool — Your Development Workflow is Unchanged

Classpresso runs after your build (npm run build), not during development. Your source code is never modified — only the compiled output in .next, dist, build, etc. You'll always see your normal Tailwind/utility classes while developing and debugging.

Performance Results

Metric Improvement
Style Recalculation 50% faster
First Paint 42% faster
Memory Usage 21% less
Runtime Overhead 0ms

Benchmarks run on 1000 complex components with Playwright + Chrome DevTools Protocol

The Problem

Utility-first CSS means elements with 10-20+ classes:

<button class="inline-flex items-center justify-center rounded-md text-sm font-medium
               transition-colors focus-visible:outline-none focus-visible:ring-2
               bg-primary text-white hover:bg-primary/90 h-10 px-4 py-2">
  Submit
</button>

Every class on every element is work for the browser: - Parse the class string - Look up each class in stylesheets - Calculate specificity and resolve conflicts - Compute final styles

With 15 classes × 500 elements = 7,500 class lookups per page load.

The Solution

Classpresso finds repeated patterns and consolidates them:

Before:

<button class="inline-flex items-center justify-center rounded-md text-sm font-medium...">Submit</button>
<button class="inline-flex items-center justify-center rounded-md text-sm font-medium...">Cancel</button>
<button class="inline-flex items-center justify-center rounded-md text-sm font-medium...">Delete</button>

After:

<button class="cp-btn bg-primary">Submit</button>
<button class="cp-btn bg-secondary">Cancel</button>
<button class="cp-btn bg-destructive">Delete</button>

Generated CSS:

.cp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* ... all consolidated utilities */
}

Result: Fewer classes = less browser work = faster rendering.

Installation

npm install classpresso --save-dev

Quick Start

# Build your project first
npm run build

# Analyze potential savings (auto-detects build directory)
npx classpresso analyze

# Apply optimizations
npx classpresso optimize

Classpresso auto-detects your build directory (.next, dist, build, .output, etc.), so you usually don't need to specify --dir.

Framework Compatibility

CSS Frameworks

Framework Classes per Element Performance Gain
Tailwind CSS 10-20+ typical Excellent
Bootstrap 5-15 typical Good
Bulma 5-10 typical Good
Tachyons 15-25+ typical Excellent
UnoCSS 10-20+ typical Excellent
Any utility CSS Varies Automatic

Build Frameworks

Classpresso works with 20+ frameworks out of the box:

Framework Build Directory SSR Flag Notes
React Meta-Frameworks
Next.js .next (default) --ssr for App Router Pages Router usually doesn't need SSR flag
Remix build --ssr recommended
Gatsby public Not needed Static only
RedwoodJS web/dist --ssr if using SSR
Vue Meta-Frameworks
Nuxt 3 .output --ssr recommended
VitePress .vitepress/dist Not needed Static docs
Gridsome dist Not needed Static only
Svelte
SvelteKit build --ssr recommended Or .svelte-kit
Other Frameworks
Astro dist --ssr for islands Static doesn't need SSR
Solid Start .output or dist --ssr recommended
Qwik dist --ssr recommended
Angular dist/[project-name] Not needed Angular 17+ uses browser/ subdir
Ember dist Not needed
Preact build or dist Depends on setup
Generic Bundlers
Vite dist Depends on framework
Webpack dist Not needed
Parcel dist Not needed
Create React App build Not needed
Static Site Generators
Eleventy (11ty) _site Not needed
Hugo public Not needed
Docusaurus build Not needed

Zero code changes required. Classpresso runs on your build output. Your React, Vue, Svelte, Solid, Qwik, Astro, Angular, or vanilla HTML stays exactly the same.

How It Works

1. You run your normal build (next build, vite build, etc.)

2. Classpresso scans the output:
   → Finds all class attributes
   → Identifies patterns that repeat
   → Calculates which are worth consolidating

3. Classpresso transforms:
   → Replaces repeated patterns with short hash classes
   → Generates CSS that maps hashes to original utilities
   → Updates HTML/JS with new class names

4. Result:
   → Same visual appearance
   → Dramatically fewer class lookups
   → Faster style recalculation on every interaction

CLI Commands

All commands auto-detect your build directory. You can override with --dir if needed.

classpresso analyze

Analyze build output and show potential optimizations without modifying files.

classpresso analyze                        # Auto-detects build dir
classpresso analyze --dir dist             # Explicit build dir
classpresso analyze --min-occurrences 3 --min-classes 3
classpresso analyze --json

Options: - -d, --dir <path> - Build directory (auto-detected if not specified) - --min-occurrences <n> - Minimum times a pattern must appear (default: 2) - --min-classes <n> - Minimum classes in a pattern (default: 2) - --ssr - Enable SSR-safe mode for hydration compatibility - --json - Output as JSON - -v, --verbose - Verbose output - --debug - Generate detailed debug log file for troubleshooting - --send-error-reports - Send error reports to configured webhook - --error-report-url <url> - Webhook URL for error reports

classpresso optimize

Apply optimizations to the build output.

classpresso optimize                       # Auto-detects build dir
classpresso optimize --dir .next           # Explicit build dir
classpresso optimize --dry-run
classpresso optimize --backup
classpresso optimize --purge-unused        # Also remove unused CSS

Options: - -d, --dir <path> - Build directory (auto-detected if not specified) - --min-occurrences <n> - Minimum times a pattern must appear (default: 2) - --min-classes <n> - Minimum classes in a pattern (default: 2) - --ssr - Enable SSR-safe mode for hydration compatibility - --dry-run - Show what would be done without making changes - --backup - Create backup files before modifying - --no-manifest - Don't generate manifest file - --purge-unused - Remove unused CSS classes after consolidation - --no-rehash - Don't re-hash content-hashed assets (see Content-Hashed Assets below) - -v, --verbose - Verbose output - --debug - Generate detailed debug log file for troubleshooting - --send-error-reports - Send error reports to configured webhook - --error-report-url <url> - Webhook URL for error reports

Content-Hashed Assets and Immutable Caching

Bundlers like Vite, Rollup, and webpack name output files after a hash of their content (index-a1b2c3d4.css), and those files are usually served with Cache-Control: immutable for long-term caching. Because optimize rewrites files in place, the served content changes while the filename hash does not - so a returning browser keeps serving the stale cached copy after a redeploy, breaking styling.

To prevent this, optimize re-hashes every content-hashed asset it modifies: the file is renamed to a new content-hash filename and every reference to it (HTML, JS, CSS url(), bundler manifests) is rewritten. The naming is deterministic, so identical input produces identical output. This is on by default and only renames files whose names already look like content hashes; stable names like styles.css are never touched.

Pass --no-rehash to keep the original filenames (for example, if you run optimize before the bundler applies its hashing step).

classpresso validate

Check for hydration safety issues before optimizing. Catches potential React/Vue/Svelte hydration mismatches.

classpresso validate                       # Auto-detects build dir
classpresso validate --dir .next
classpresso validate --json

Example output:

☕ Classpresso - Hydration Safety Validator

📊 Hydration Safety Summary

  Patterns analyzed:    22
  Hydration-safe:       17
  Server-only:          3
  Client-only:          2
  Mergeable (props):    1

⚠️  Found 5 patterns that may cause hydration issues:

  1. "flex items-center gap-4"
     Status: SERVER-ONLY
     Location: server/page.html:47
     Fix: This pattern only appears in server-rendered HTML...

💡 Recommendations

  ⚠️  Mixed server/client patterns detected.
     Use "classpresso optimize --ssr" to only consolidate safe patterns.

Options: - -d, --dir <path> - Build directory (auto-detected if not specified) - --json - Output as JSON - -v, --verbose - Verbose output - --debug - Generate detailed debug log file for troubleshooting

classpresso unused

Analyze CSS for unused classes. Find dead CSS that can be removed.

classpresso unused                         # Auto-detects build dir
classpresso unused --dir dist
classpresso unused --verbose               # Show file breakdown
classpresso unused --json

Example output:

☕ Classpresso - Unused CSS Analyzer

📊 Summary

  CSS files scanned:    3
  Total CSS rules:      1,247
  Classes used:         892
  Classes unused:       47

💾 Size Impact

  Unused CSS bytes:     12,340 (12.1 KB)
  Gzip estimate:        3,120 (3.0 KB)

🔝 Top 10 Unused Classes (by size)

  1. hover\:bg-gradient-to-r                           234 B
  2. focus\:ring-offset-4                              189 B
  ...

💡 Recommendations

  ⚠️  Found 12.1 KB of unused CSS.
     Run "classpresso optimize --purge-unused" to remove these classes.

Options: - -d, --dir <path> - Build directory (auto-detected if not specified) - --limit <n> - Number of top unused classes to show (default: 20) - --json - Output as JSON - -v, --verbose - Verbose output (show file breakdown) - --debug - Generate detailed debug log file for troubleshooting

classpresso report

Generate a report from an existing manifest.

classpresso report                         # Auto-detects build dir
classpresso report --dir .next
classpresso report --format json
classpresso report --format html > report.html

Options: - -d, --dir <path> - Build directory (auto-detected if not specified) - --format <type> - Output format: text, json, html (default: text)

Integration Examples

With auto-detection, most integrations are now simpler:

Next.js

{
  "scripts": {
    "build": "next build && classpresso optimize --ssr",
    "build:analyze": "next build && classpresso analyze"
  }
}

Vite / Create React App / Generic

{
  "scripts": {
    "build": "vite build && classpresso optimize"
  }
}

Classpresso auto-detects dist, build, or your framework's output directory.

Astro

Classpresso fully supports Astro static, SSR, and hybrid builds.

Static Build (default):

{
  "scripts": {
    "build": "astro build && classpresso optimize --dir dist"
  }
}

SSR/Hybrid Build (with React/Vue/Svelte islands):

{
  "scripts": {
    "build": "astro build && classpresso optimize --dir dist --ssr"
  }
}

Configuration file:

// classpresso.config.js
module.exports = {
  buildDir: 'dist',
  // Use --ssr flag if you have interactive islands with client:* directives
  ssr: false,
};

Classpresso automatically detects Astro's build structure: - dist/**/*.html - Static HTML pages - dist/_astro/**/*.js - Client-side JavaScript - dist/_astro/**/*.css - Compiled CSS - dist/server/**/*.mjs - Server code (SSR mode) - dist/client/_astro/**/* - Client assets (SSR mode)

Nuxt 3

{
  "scripts": {
    "build": "nuxt build && classpresso optimize --dir .output --ssr"
  }
}

SvelteKit

{
  "scripts": {
    "build": "vite build && classpresso optimize --dir build --ssr"
  }
}

Remix

{
  "scripts": {
    "build": "remix build && classpresso optimize --dir build --ssr"
  }
}

Solid Start

{
  "scripts": {
    "build": "vinxi build && classpresso optimize --dir .output --ssr"
  }
}

Qwik

{
  "scripts": {
    "build": "qwik build && classpresso optimize --dir dist --ssr"
  }
}

Angular

{
  "scripts": {
    "build": "ng build && classpresso optimize --dir dist/my-app"
  }
}

For Angular 17+, the output is in dist/[project-name]/browser.

Gatsby

{
  "scripts": {
    "build": "gatsby build && classpresso optimize --dir public"
  }
}

Eleventy (11ty)

{
  "scripts": {
    "build": "eleventy && classpresso optimize --dir _site"
  }
}

Hugo

hugo && classpresso optimize --dir public

Docusaurus

{
  "scripts": {
    "build": "docusaurus build && classpresso optimize --dir build"
  }
}

VitePress

{
  "scripts": {
    "build": "vitepress build && classpresso optimize --dir .vitepress/dist"
  }
}

SSR-Safe Mode

For *

Extension points exported contracts — how you extend this code

FrameworkHint (Interface)
* Framework hints from package.json dependencies
src/config.ts
ExcludeConfig (Interface)
(no doc)
src/types/index.ts
LoggerOptions (Interface)
(no doc)
src/utils/logger.ts
RehashRename (Interface)
(no doc)
src/core/rehasher.ts
ReportOptions (Interface)
(no doc)
src/cli/report.ts
ClasspressoConfig (Interface)
(no doc)
src/types/index.ts
Logger (Interface)
(no doc)
src/utils/logger.ts
RehashResult (Interface)
(no doc)
src/core/rehasher.ts

Core symbols most depended-on inside this repo

parseUtilityClass
called by 64
src/core/css-generator.ts
isNonFlattenableClass
called by 34
src/core/scanner.ts
formatBytes
called by 33
demo/benchmark.js
logStep
called by 27
src/utils/logger.ts
escapeRegex
called by 22
src/utils/regex.ts
error
called by 19
src/utils/logger.ts
containsDynamicPrefix
called by 16
src/core/scanner.ts
validateConfig
called by 15
src/config.ts

Shape

Function 143
Interface 30
Method 11

Languages

TypeScript100%

Modules by API surface

src/utils/logger.ts28 symbols
src/types/index.ts13 symbols
src/utils/files.ts12 symbols
src/core/scanner.ts10 symbols
src/core/rehasher.ts9 symbols
src/core/css-generator.ts9 symbols
src/core/transformer.ts8 symbols
src/core/metrics.ts8 symbols
src/cli/unused.ts8 symbols
src/config.ts7 symbols
demo/generate-report.js7 symbols
src/utils/error-reporter.ts6 symbols

For agents

$ claude mcp add classpresso \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact