svg-sprite is the core engine for creating SVG sprites, offering both a CLI and a Node.js API. gulp-svg-sprite is a Gulp plugin that wraps svg-sprite to integrate it into Gulp streaming workflows. svg-sprite-loader is a Webpack loader that processes SVG files into sprites during the bundling process. While all three rely on the same underlying sprite generation logic, they differ significantly in how they integrate with build tools, configure output modes, and handle asset management.
Generating SVG sprites is a common optimization technique in frontend development to reduce HTTP requests and manage icon systems efficiently. The ecosystem offers three main approaches: the core svg-sprite library, the Gulp plugin gulp-svg-sprite, and the Webpack-specific svg-sprite-loader. While they share the same underlying engine, their integration points and configuration models differ significantly.
svg-sprite is the standalone core library.
// svg-sprite: Direct Node.js API usage
const SVGSpriter = require('svg-sprite');
const fs = require('fs');
const spriter = new SVGSpriter({
dest: 'dist/sprites',
mode: {
css: { dest: 'css', sprite: 'sprite.css' }
}
});
spriter.add('src/icons/icon1.svg', null, fs.readFileSync('src/icons/icon1.svg', 'utf8'));
spriter.add('src/icons/icon2.svg', null, fs.readFileSync('src/icons/icon2.svg', 'utf8'));
spriter.compile((error, result) => {
if (error) throw error;
for (const mode of Object.values(result)) {
for (const resource of Object.values(mode)) {
fs.writeFileSync(resource.path, resource.contents);
}
}
});
gulp-svg-sprite wraps the core library for Gulp streams.
.pipe().// gulp-svg-sprite: Gulp pipeline integration
const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');
gulp.task('sprites', () => {
return gulp.src('src/icons/*.svg')
.pipe(svgSprite({
mode: {
css: { dest: 'css', sprite: 'sprite.css' }
}
}))
.pipe(gulp.dest('dist/sprites'));
});
svg-sprite-loader integrates sprite generation into Webpack.
// svg-sprite-loader: Webpack configuration
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.svg$/,
use: [
{
loader: 'svg-sprite-loader',
options: {
spriteFilename: 'img/sprite.[hash:8].svg'
}
},
'svgo-loader'
]
}
]
}
};
All three packages support multiple sprite modes (CSS, View, Symbol, Stack), but the way you configure them varies based on the integration layer.
svg-sprite requires explicit mode configuration in the constructor.
css, view, symbol, stack.// svg-sprite: Explicit mode config
const config = {
mode: {
symbol: {
dest: 'symbols',
sprite: 'sprite.symbol.svg',
example: true // Generate example page
}
}
};
const spriter = new SVGSpriter(config);
gulp-svg-sprite passes configuration directly to the core library.
// gulp-svg-sprite: Config passed to plugin
.pipe(svgSprite({
mode: {
symbol: {
dest: 'symbols',
sprite: 'sprite.symbol.svg',
example: true
}
}
}))
svg-sprite-loader configures modes via loader options.
symbol or stack modes for inline usage.publicPath for asset URLs.svg-sprite-loader specific syntax for extracting sprite content.// svg-sprite-loader: Loader options
use: [
{
loader: 'svg-sprite-loader',
options: {
mode: 'symbol',
escape: true,
spriteFilename: 'sprite.[hash:8].svg'
}
}
]
Handling file hashes and cache busting is critical for production deployments. The approaches differ based on whether the tool is aware of your bundler.
svg-sprite has no built-in hashing.
// svg-sprite: Manual hashing implementation
const crypto = require('crypto');
const hash = crypto.createHash('md5').update(contents).digest('hex');
const filename = `sprite.${hash}.svg`;
// Write file with hashed name manually
gulp-svg-sprite relies on Gulp plugins for hashing.
gulp-rev or gulp-hash in the pipeline.// gulp-svg-sprite: Using gulp-rev for hashing
const rev = require('gulp-rev');
gulp.src('src/icons/*.svg')
.pipe(svgSprite({ mode: { css: {} } }))
.pipe(rev())
.pipe(gulp.dest('dist'))
.pipe(rev.manifest());
svg-sprite-loader handles hashing automatically via Webpack.
[hash] placeholders in filenames.// svg-sprite-loader: Automatic hashing
options: {
spriteFilename: 'img/sprite.[hash:8].svg' // Webpack handles the hash
}
How you reference the generated sprite in your HTML or JavaScript depends on the output mode and the tool used.
svg-sprite generates static files.
<!-- svg-sprite: Standard HTML reference -->
<link rel="stylesheet" href="css/sprite.css">
<div class="icon icon-home"></div>
<!-- Or inline SVG -->
<svg class="icon"><use xlink:href="sprite.symbol.svg#icon-home"></use></svg>
gulp-svg-sprite produces the same static files.
<!-- gulp-svg-sprite: Same static output -->
<link rel="stylesheet" href="css/sprite.css">
<div class="icon icon-home"></div>
svg-sprite-loader allows dynamic imports.
// svg-sprite-loader: Dynamic import in JS
import iconHome from 'icons/home.svg';
import iconUser from 'icons/user.svg';
// Usage in React component
<svg>
<use xlinkHref={iconHome.url} />
</svg>
svg-sprite is the source of truth.
gulp-svg-sprite depends on Gulp's ecosystem.
svg-sprite-loader is Webpack-specific.
| Feature | svg-sprite | gulp-svg-sprite | svg-sprite-loader |
|---|---|---|---|
| Integration | 🛠️ Node.js API / CLI | 🔄 Gulp Streams | 📦 Webpack Loader |
| Configuration | 📝 Manual JS Object | 📝 Gulp Plugin Options | 📝 Webpack Rule Options |
| Hashing | ❌ Manual Implementation | ⚙️ Via gulp-rev | ✅ Automatic (Webpack) |
| Output | 📄 Static Files | 📄 Static Files | 📦 Bundled Assets |
| Usage | 🌐 Standard HTML/CSS | 🌐 Standard HTML/CSS | 💻 JS Module Imports |
| Best For | 🎯 Custom Scripts | 🏭 Gulp Pipelines | ⚡ Modern Webpack Apps |
svg-sprite is the foundation 🏗️—use it when you need maximum control or aren't using a heavy bundler. It's the most future-proof choice since wrappers depend on it.
gulp-svg-sprite is the legacy bridge 🌉—perfect for maintaining existing Gulp 4 workflows but avoid it for new projects unless Gulp is your standard.
svg-sprite-loader is the modern integrator 🔌—ideal for Webpack-based applications where you want sprites treated as modules with automatic optimization and hashing.
Final Thought: If starting a new project today, prefer svg-sprite-loader for Webpack or svg-sprite directly for custom setups. Reserve gulp-svg-sprite for maintaining legacy build systems.
Choose gulp-svg-sprite if your build pipeline is already heavily invested in Gulp and you need to process SVGs as part of a streaming task chain. It is best suited for legacy projects or teams that prefer Gulp's task-based automation over module bundlers. However, be aware that Gulp plugins often lag behind the core library in feature updates.
Choose svg-sprite if you want direct control over sprite generation without being tied to a specific bundler or task runner. It is ideal for custom Node.js scripts, CLI-only workflows, or when you need to use the latest features immediately without waiting for plugin wrappers to update. This is the most flexible option for non-standard build environments.
Choose svg-sprite-loader if you are using Webpack and want SVG sprites to be generated automatically as part of your module bundling process. It simplifies configuration by handling sprite creation within the loader chain, making it easy to reference sprites directly in JavaScript or CSS modules. This is the standard choice for modern Webpack-based React or Vue applications.
gulp-svg-sprite is a Gulp plugin wrapping around svg-sprite which takes a bunch of SVG files, optimizes them and bakes them into SVG sprites of several types:
<view> elements, useful for foreground images as well,<defs> element,<symbol> elementThis document covers only gulp specific installation and configuration aspects. For a full list of features and options, please see the svg-sprite manual.
First, install gulp-svg-sprite as a development dependency:
npm install --save-dev gulp-svg-sprite
Then, add it to your gulpfile.js:
const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');
gulp.src('path/to/assets/*.svg')
.pipe(svgSprite(/* ... Insert your configuration here ... */))
.pipe(gulp.dest('out'));
NOTICE: By default, svg-sprite doesn't send any files downstream unless you configure it. There are tons of options available — please see below for some basic examples. Also, you should possibly take care of errors that might occur.
As options argument you may provide a main configuration object as described in the svg-sprite manual. Configuration-wise, svg-sprite and gulp-svg-sprite differ only in one respect:
Type: String
Default value: '.'
With Gulp, there is no need to specifiy a main output directory, as the generated files are piped to the next step of the running task anyway. The options.dest value (if given) is simply ignored.
In this very basic example, mostly default settings will be applied to create a traditional CSS sprite (bundle of SVG sprite and CSS stylesheet).
const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');
// Basic configuration example
const config = {
mode: {
css: { // Activate the «css» mode
render: {
css: true // Activate CSS output (with default options)
}
}
}
};
gulp.src('**/*.svg', { cwd: 'path/to/assets' })
.pipe(svgSprite(config))
.pipe(gulp.dest('out'));
The following files and directories are created:
out/
├─ css/
│ ├─ sprite.css
│ ├─ svg/
│ │ ├─ sprite.css-495d2010.svg
The cryptical looking part in the SVG's file name is the result of svg-sprite's cache busting feature which is enabled by default for CSS sprites. We'll turn this off in the next example.
const { src, dest, parallel } = require('gulp');
const svgSprite = require('gulp-svg-sprite');
// Basic configuration example
const svgspriteConfig = {
mode: {
css: { // Activate the «css» mode
render: {
css: true // Activate CSS output (with default options)
}
}
}
};
function buildSvg() {
return src('**/*.svg', { cwd: 'src/assets' })
.pipe(svgSprite(svgspriteConfig))
.pipe(dest('out'));
}
exports.default = parallel(buildSvg);
The following example is a little more complex:
const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');
// More complex configuration example
const config = {
shape: {
dimension: { // Set maximum dimensions
maxWidth: 32,
maxHeight: 32
},
spacing: { // Add padding
padding: 10
},
dest: 'out/intermediate-svg' // Keep the intermediate files
},
mode: {
view: { // Activate the «view» mode
bust: false,
render: {
scss: true // Activate Sass output (with default options)
}
},
symbol: true // Activate the «symbol» mode
}
};
gulp.src('**/*.svg', { cwd: 'path/to/assets' })
.pipe(svgSprite(config))
.pipe(gulp.dest('out'));
The following files and directories are created:
out/
├─ intermediate-svg
│ ├─ weather-clear.svg
│ ├─ weather-snow.svg
│ ├─ weather-storm.svg
├─ symbol/
│ ├─ svg/
│ ├─ sprite.symbol.svg
├─ view/
│ ├─ sprite.scss
│ ├─ svg/
│ ├─ sprite.view.svg
Errors might always happen — maybe there are some corrupted source SVG files, the default SVGO plugin configuration is too aggressive or there's just an error in svg-sprite's code. To make your tasks more robust, you might consider using plumber and adding your custom error handling:
const gulp = require('gulp');
const svgSprite = require('gulp-svg-sprite');
const plumber = require('gulp-plumber');
// Basic configuration example
const config = {
mode: {
css: {
render: {
css: true
}
}
}
};
gulp.src('**/*.svg', { cwd: '' })
.pipe(plumber())
.pipe(svgSprite(config))
.on('error', function(error) {
/* Do some awesome error handling ... */
})
.pipe(gulp.dest('out'));
For more advanced features like
please refer to the svg-sprite manual.
Please refer to the GitHub releases for a complete release history.
Copyright © 2018 Joschi Kuphal joschi@kuphal.net / @jkphl. svg-sprite is licensed under the terms of the MIT license. The contained example SVG icons are part of the Tango Icon Library and belong to the Public Domain.