How to automatically optimize SVG files with esbuild

Posted . Visible to the public.

SVG files often contain redundant information, like editor metadata or hidden elements. When esbuild handles your static assets, you can easily optimize SVG files using svgo Show archive.org snapshot as a plugin. Here is how to do it.

Adding svgo as an esbuild plugin

  1. Add the svgo package to your project's package.json
  2. Adjust your esbuild.config.js like so:
const esbuild = require('esbuild')
const svgo = require('svgo')

const options = {
  // ...
  loader: {
    // ...
    '.svg': 'copy', // this may be different for you, but esbuild must be configured to handle SVGs
  },
  plugins: [
    // ...
    {
      name: 'svgo',
      setup(build) {
        build.onLoad({ filter: /\.svg$/ }, async ({ path }) => {
          if (path.includes('/fonts/')) return
          if (path.includes('/node_modules/')) return

          const svg = await fs.promises.readFile(path, 'utf8')
          const { data } = svgo.optimize(svg)

          return { contents: data, loader: 'copy' }
        })
      }
    }
  ]
}

esbuild.build(options)

That's it. After your next build, all SVGs should be optimized with svgo's default configuration.
Optimized files are placed in the output directory. Source files stay unchanged.

Note that we skip optimizing any files in paths fonts or node_modules. Those are usually optimized already, or changes would at least have undesired effects.

Adjusting svgo's configuration

The default should be fine for most projects. To fine-tune its config, you may pass an options argument to the svgo.optimize call.

Usually, you want to keep the default and specify only a few settings. Do this by using svgo's preset-default plugin and passing overrides.
Example:

          const { data } = svgo.optimize(svg, {
            plugins: [
              { name: 'preset-default', params: { overrides: { convertTransform: false } } },
            ],
          })

While not recommended, you may also not use preset-default to keep everything disabled, and use only those features that you explicitly enable.

Arne Hartherz
Last edit
Henning Koch
License
Source code in this card is licensed under the MIT License.
Posted by Arne Hartherz to makandra dev (2025-03-20 18:14)