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

rollup-plugin-smart-cache

v1.0.0

Published

Rollup plugin with persistent hash-based cache that skips bundling when inputs haven't changed

Readme

rollup-plugin-smart-cache

A Rollup plugin that uses persistent hash-based cache to completely skip bundling when inputs haven't changed. Perfect for large projects that need fast incremental builds.

Why This Exists

Traditional build caches (like timestamp-based) still execute Rollup partially, which can be slow for large projects. This plugin computes a deterministic hash of all inputs and completely skips Rollup execution when the hash matches a cached build, dramatically reducing build times for large codebases.

Installation

npm install --save-dev rollup-plugin-smart-cache

Basic Usage

import { smartCache } from 'rollup-plugin-smart-cache'

export default {
  input: 'src/index.js',
  output: {
    file: 'dist/bundle.js',
    format: 'es',
  },
  plugins: [
    smartCache({
      inputs: ['src/**/*', 'package.json'],
      ignore: ['node_modules/**', 'dist/**'],
      env: ['NODE_ENV'],
    }),
  ],
}

API Reference

smartCache(options)

Options

  • inputs (required): string[] - Glob patterns for files to include in hash calculation
  • cacheDir (optional): string - Cache directory (default: '.rollup-smart-cache')
  • ignore (optional): (string | RegExp)[] - Files/directories to ignore
  • env (optional): string[] - Environment variables that affect the build
  • platform (optional): boolean - Include platform in hash (default: false)
  • node (optional): boolean - Include Node version in hash (default: false)
  • debug (optional): boolean - Enable debug logging (default: false)
  • legacyCacheDir (optional): string - Migrate from existing cache directory
  • lockTimeout (optional): number - Lock timeout in milliseconds (default: 300000 = 5 minutes)

Rules

  • inputs is mandatory - no magic defaults
  • No callbacks or dynamic hash logic
  • Defaults are conservative (fail-safe)
  • All paths normalized for cross-platform compatibility
  • lockTimeout configurable for large builds (default: 5 minutes)

Presets

Basic Preset

Simple single-bundle setup:

import { basic } from 'rollup-plugin-smart-cache/presets'

export default {
  plugins: [basic()],
}

Multi-Bundle Preset

For projects with multiple Rollup configs:

import { multiBundle } from 'rollup-plugin-smart-cache/presets'

export default {
  plugins: [multiBundle()],
}

How Hashing Works

The plugin computes a SHA-256 hash of:

  1. File contents: Normalized for CRLF/LF differences (cross-platform consistency)
  2. File paths: Normalized to POSIX format (forward slashes)
  3. File sizes: Included as metadata
  4. Optional metadata:
    • Node version (if node: true)
    • Platform (if platform: true)
    • Environment variables (from env option)

Files are sorted deterministically (case-insensitive alphabetical) to ensure order-independent hashing.

Cache Invalidation Rules

Cache is invalidated when:

  • Input file contents change
  • Input files are added/removed
  • Environment variables change (if specified in env)
  • Node version changes (if node: true)
  • Platform changes (if platform: true)
  • Cache metadata doesn't match
  • Output files are missing or corrupted

Debugging Guide

Enable debug mode to see detailed information:

smartCache({
  inputs: ['src/**/*'],
  debug: true,
})

Debug output includes:

  • Hash computation details
  • Files included/excluded
  • Cache hit/miss reason
  • Invalidation reason
  • Lock acquisition/release
  • Performance metrics (hash time, lookup time, write time, time saved)

When NOT to Use

The plugin automatically disables in unsafe scenarios:

  • Watch mode: Detected via this.meta.watchMode
  • Multiple output formats: Different formats can produce different outputs
  • Non-deterministic plugins: Blacklist includes rollup-plugin-replace with timestamps
  • Capacitor builds: Detected via CAPACITOR_PLATFORM, --capacitor flag, or capacitor.config.json

In these cases, the plugin logs a warning and allows normal Rollup execution.

Migration from Timestamp-Based Cache

The plugin detects legacy timestamp-based cache and invalidates it gracefully on first run:

  1. Detects existence of output directories without smart cache
  2. Removes legacy outputs to ensure clean state
  3. Next build uses smart cache

For explicit migration, use legacyCacheDir:

smartCache({
  inputs: ['src/**/*'],
  legacyCacheDir: '.old-cache',
})

Integration with NPM Scripts

Add to your package.json:

{
  "scripts": {
    "build": "rollup -c",
    "build:cached": "rollup -c --plugin smart-cache",
    "clean:smart-cache": "rimraf .rollup-smart-cache"
  }
}

Troubleshooting

Cache not working

  1. Check debug logs: debug: true
  2. Verify inputs include all relevant files
  3. Check for unsafe conditions (watch mode, etc.)
  4. Ensure cache directory is writable

Wrong cache hit

  1. Verify ignore patterns exclude outputs
  2. Check environment variables are included if they affect build
  3. Ensure platform/node options match your needs

Performance issues

  1. Reduce number of input files (better ignore patterns)
  2. Increase lockTimeout for large builds
  3. Check disk I/O performance

Performance Tips

Expected Performance Gains

Performance metrics based on EdenwareApps/Megacubo project:

  • Full build: 45-60 seconds
  • Cache hit: 3-8 seconds (file writing only)
  • Time saved: ~85-90%
  • Comparison: Superior to timestamp-based cache that still executes Rollup partially

Optimization Tips

  1. Minimize inputs: Only include files that affect the build
  2. Use ignore patterns: Exclude outputs, node_modules, temp files
  3. Environment variables: Only include vars that actually affect output
  4. Platform/node hashing: Only enable if builds differ between platforms/Node versions

License

MIT