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

jcrushsvg

v1.1.40

Published

Javascript based SVG deduplicator and compressor

Readme

npm

JCrush SVG

Deduplicates and compresses SVG files using Javascript.

It creates Javascript files that provide the SVG code.

  • Works best on groups of SVG files that have already been compressed with a regular SVG compressor. (For the use-case this was created for it resulted in 83% compression)
  • Uses JCrush. See that project for more info (and an in-built plugin for deduplicating Javascript code).
  • You should merge, minify, and reprocess the main output file produced with this module using JCrush for further optimization.
  • If you don't want deduplication and just need something to optimize SVG/HTML DOM code (more than minifiers), see HyperCrush.

Installation

This is a Node.JS module available from the Node Package Manager (NPM).

https://www.npmjs.com/package/jcrushsvg

Here's the command to download and install from NPM:

npm install jcrushsvg -S

or with Yarn:

yarn add jcrushsvg

Setup Instructions

  1. Place all relevant SVG files in one directory:

    • Example: /src/svg
  2. Choose a processing method:

    • Decide whether to use the terminal, a custom script, or Gulp to process the directory with this module.
    • Refer to the Usage section below for further instructions.
  3. Modify your Javascript code:

    • Instead of using the SVG images in an <img> tag, call a function with the file's basename (slug).
    • The usage differs based on the bundle option:
      • If bundle is false (default):
        • The functionality is asynchronous. To load the SVG code into a DOM element, use:
          svg('main-logo', document.getElementById("logo"))
        • Note: This will replace whatever is already inside the #logo element, so plan your code accordingly.
      • If bundle is true:
        • The SVG code is stored in the main JS file. The function will return the SVG code like so:
          var svgCode = svg('main-logo')
  4. Include the main Javascript outFile in your HTML:

    • Or, use some automation to merge it into your scripts.
    • Note: There's no need to include each individual image's corresponding JS file.
  5. Merge/minify/compress the main outFile:

    • You should merge, minify, or compress the main outFile as you would with your own code.
    • Note: This module leaves that file in a human-readable state.

Usage

From the Terminal

It may be sufficient to just run:

node node_modules/jcrushsvg --inDir="/src/svg" --outDir="/svg" --outFile="svg.js"

...once and you're done.

Write a Custom Script

Create a file svgTask.js with the contents:

import jcrushSVG from 'jcrushsvg';
let opts = { inDir: '/src/svg', outDir: '/svg', outFile: 'svg.js', processSVG:(filePath, svgContent) => {
  // Check there is no version or it's v1.1... that's the cool one.
  if (svgContent.includes('version=') && !svgContent.includes('version="1.1"')) {
    throw new Error(`SVG in ${filePath} does not have version="1.1". Ensure you set "SVG Profile: SVG 1.1" in save-as dialogue of Adobe Illustrator.`);
  }
  // Check for style tags, not on my watch.
  if (svgContent.match(/<style[^>]*>[\s\S]*?<\/style>/g)) {
    throw new Error(`SVG in ${filePath} contains <style> tags, which are not allowed. Ensure you set "CSS Properties: Presentation Attributes" in save-as dialogue of Adobe Illustrator.`);
  }
  // Check if it uses CSS for colors - get outta here with that!
  if (/style\s*=\s*["'][^"']*color\s*:/i.test(svgContent)) {
    throw new Error(`SVG in ${filePath} uses CSS for colors, which is not allowed. Ensure you set "CSS Properties: Presentation Attributes" in save-as dialogue of Adobe Illustrator.`);
  }
  return svgContent;
}};
jcrushSVG(opts);

Then run this command:

node svgTask

...whenever you've added a new SVG file to the directory.

With Gulp

In your gulpfile.mjs:

Step 1: Import JCrush SVG

import jcrushSVG from 'jcrushsvg';

Step 2: Create a Gulp Task

gulp.task('svg', (done) => {
  let opts = { inDir: '/src/svg', outDir: '/svg', outFile: 'svg.js', checkNew: 1 };
  jcrushSVG(opts);
  done(); // Signal completion
});

Step 3: (Optional) Run JCrush SVG Before Minification

To run JCrush SVG before your minification tasks, add JCrush SVG in series before other tasks, such as in this example:

gulp.task('default', gulp.series(
  'svg' // Run it before your other stuff.  Probably.
  gulp.parallel('minify-css', 'minify-js', 'minify-html'),
));

Alternatively don't include it in your default gulp task. Run the task manually, e.g. gulp svg.


Parameters

opts (Object, optional)

A configuration object with the following properties:

  • inDir (String, default: ''):

    • The folder where the SVG files are. You MUST put this in.
  • outDir (String, default: ''):

    • The folder where the JS files will be outputted. Will assume same as inDir if not supplied, but that isn't ideal.
  • outFile (String, default: 'svg.js'):

    • The name of the main JS file to create that will have the function to provide SVG code.
  • funcName (String, default: svg):

    • The name of the function to create that will provide SVG code.
  • bundle (Boolean, default: false):

    • If true, will load all the SVG code into the main outFile instead of separate files. The SVGs are preloaded and the SVG function will return SVG code as a string.
    • If false, will load SVGs from individual JS files on an as-needed basis, reducing loading overhead. The SVG function accepts a DOM element and will replace its contents with the SVG once it is loaded.
  • param (Boolean, default false):

    • If 'true' will paramaterize the replacement variables for silghtly shorter output.
    • If 'false' will included the replacement variables in the function body.
  • let (Boolean, default true):

    • If 'true' will prepend the main function with a let keyword.
    • If 'false' will omit let keyword.
  • appendExt (Boolean, default: true):

    • If true, will create the individual JS files with ".svg.js" extensions.
    • If false, will create the individual JS files with just ".js" extensions.
  • maxLen (Number, default: 40):

    • The maximum length of substrings to consider. Setting this higher will slow things down.
  • resVars (Array, default: ['el', 'k']): Supply an array of variable names that JCrush must NOT use for some reason. This module will reserve 'el' and 'k', so don't use those for anything else.

  • processSVG (Function, default: null): A function to run custom validation/preprocessing on each SVG tag. 2 params: filePath, svgContent. Throw error to halt processing. Return the changed SVG code.

  • processJS (Function, default: null): A function to run custom processing on JS output. 2 params: filePath, jsContent. Throw error to halt processing. Return the changed JS code.

  • checkNew (Boolean, default: false):

    • If true, will not run if the outFile exists and is newer than all of the files in inDir.
    • If false, will re-run everytime.
  • prog (Boolean, default: true):

    • If true, will output console messages when making progress.
    • If false, will work silently.
  • fin (Boolean, default: true):

    • If true, will output a final console message about bytes saved or failure.
    • If false, will remain silent.

Additionally; JCrush SVG can accept the options of the underlying JCrush package, however if they're not listed above then changing them may break this module's functionality. Tread carefully.


Dynamic Colors

This is an example of a use-case of this module where a number of SVGs were designed to be dynamically recolored with Javascript.

The goal is to be able to control the SVG's colors and opacity via Javascript.

  • The SVGs were all made with 2 colors, the main color being #64bc41 (moderate green)
  • A secondary color was made dark-grey (evidently using black is not compatible with this!)
  • Some shapes were made with 20% opacity, but that would need to be fine tuned based on the dynamic color too.

Approach:

  • Use the processSVG callback to add 3 placeholders to: #64bc41, other colors, and opacity values. The placeholder selected was an appropriate emoji.
  • Use the processJS callback to rectify the placeholders to suitable template literals, and modify the function to accept corresponding parameters.
  • Use the resVars feature to reserve the custom parameters.

The custom SVG processing script:

const jcrushSVG = require('jcrushsvg');

jcrushSVG({ inDir: './src/img/items', outFile: './src/svgItems.js',
  bundle: 1, maxLen: 120, funcName: 'svgItems', resVars: ['bg', 'fg', 'op'],
  processSVG: (filePath, svgContent) => {
    // Replaces color codes with placeholders
    return svgContent.replace(new RegExp('#64bc41', 'gi'), '🟩') // Background
      .replace(/#[a-fA-F0-9]{6}|#[a-fA-F0-9]{3}/gi, '⬛') // Foreground
      .replace(/opacity="([^"]+)"/gi, 'opacity="🔲"'); // Opacity
  },
  processJS:(filePath, jsContent) => {
    return jsContent.replace('k =>', '(k, bg, fg, op) =>')
      .replace(/🟩/g, '${bg}')
      .replace(/⬛/g, '${fg}')
      .replace(/🔲/g, '${op}');
  },
});

Now our app can specify the colors it needs:

// Calls svgItems() to get the SVG code based on item's attributes.
let itemImage = item => svgItems(item.key, item.bgColor, item.fgColor, item.opacity);

Contributing

https://github.com/braksator/jcrushsvg

In lieu of a formal style guide, take care to maintain the existing coding style.