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

@pplancq/svg-core

v2.1.1

Published

A functions for asynchronously loading SVG files into the DOM

Readme

@pplancq/svg-core

Lightweight library to asynchronously load and insert SVG files into the DOM, with sanitization and attribute merging.

📝 Description

@pplancq/svg-core provides utilities to fetch an SVG (from a URL, a local path, or a data URI), sanitize it with DOMPurify, and merge its attributes into an existing SVG element when needed. The package avoids duplicate concurrent requests and throws explicit errors for invalid content.

Main goals:

  • Load SVGs asynchronously.
  • Protect against malicious SVG content using DOMPurify.
  • Provide a simple API to reuse/merge SVGs into the DOM.

⚙️ Installation

npm install @pplancq/svg-core

🚀 Quick start

import { getSvg } from '@pplancq/svg-core';

// Load an SVG from a URL and append it to the DOM
const svg = await getSvg('https://example.com/my-icon.svg');
document.body.appendChild(svg);

// Load a data URI SVG (base64 or URL-encoded)
const dataUri = 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><circle r="10"/></svg>';
const svgFromData = await getSvg(dataUri);
document.body.appendChild(svgFromData);

// Merge a fetched SVG into an existing SVG element (useful to preserve element references)
const target = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
const merged = await getSvg('https://example.com/icon.svg', target);
// `merged` === `target` (mutated) — contains the attributes and content of the fetched SVG

🔌 API

📥 getSvg(path: string | URL, svgElement?: SVGSVGElement, sanitizeConfig?: SanitizeConfig): Promise

  • Fetches SVG content from path (URL, path, or data URI data:image/svg+xml) and returns an SVGSVGElement ready to be inserted into the DOM.
  • Parameters:
    • path — string or URL pointing to the SVG or a data URI.
    • svgElement — (optional) existing SVG element that will receive the attributes and content of the downloaded SVG.
    • sanitizeConfig — (optional) sanitization configuration to customize sanitization behavior. ⚠️ WARNING: Only use with trusted SVG sources.
  • Important behavior:
    • SVGs are sanitized via DOMPurify with SVG profiles enabled by default.
    • You can customize sanitization using the sanitizeConfig parameter (see Custom Sanitization below).
    • Concurrent calls to the same URL are deduplicated to avoid redundant network requests.
    • If path is a data URI, the function decodes the data (base64 or URL-encoded) without a network request.
  • Possible errors:
    • InvalidSvgError — the HTTP response does not indicate Content-Type: image/svg+xml.
    • ContentSvgError — the retrieved content does not contain a valid <svg> element.

🔒 Custom Sanitization

By default, all SVG content is sanitized using DOMPurify to prevent XSS attacks. However, some legitimate SVG features (like animations) may be removed by the default configuration.

If you control your SVG sources and need to allow specific elements or attributes, you can pass a sanitizeConfig object:

import { getSvg } from '@pplancq/svg-core';

// Allow SVG animation elements and attributes
const svg = await getSvg('/animated-spinner.svg', undefined, {
  allowTags: ['animateTransform', 'animate', 'animateMotion'],
  allowAttributes: ['from', 'to', 'dur', 'repeatCount', 'values', 'keyTimes'],
});

Available configuration options:

  • allowTags — Array of additional tag names to allow
  • allowAttributes — Array of additional attribute names to allow
  • forbidTags — Array of tag names to explicitly forbid
  • forbidAttributes — Array of attribute names to explicitly forbid
  • allowDataAttributes — Boolean to allow data-* attributes

⚠️ Security Warning:

The sanitizeConfig option should only be used when:

  • You control and trust the source of your SVG files
  • You understand the security implications of allowing specific elements/attributes
  • You have validated that your configuration doesn't introduce XSS vulnerabilities

DO NOT use custom sanitization configurations with user-uploaded SVGs or SVGs from untrusted sources.

🔁 mergeSvgContent(source: SVGSVGElement, target: SVGSVGElement): SVGSVGElement

  • Merges attributes from source into target (uses mergeAttributes) then copies the content (innerHTML) of source into target.
  • Mutates target and returns it.
  • Usage: useful if you want to create an SVG element manually and inject fetched content into it.

🔒 Security & CORS

  • Content is sanitized with DOMPurify (SVG profile + filters) to reduce XSS risk via SVG.
  • The server must return the Content-Type: image/svg+xml header for the fetch to be accepted; otherwise InvalidSvgError is thrown.
  • For cross-origin requests, the server must allow requests via CORS for fetch to work from a browser.

⚡ Performance

  • The module deduplicates simultaneous requests to the same resource (in-flight promise cache) to avoid network overload.
  • For massive use cases (many icons), consider application-side caching or an SVG sprite to reduce the number of requests.

♿ Accessibility

  • The package accounts for SVG content security — but accessibility (alternative text, roles, titles) depends on how you integrate SVGs in your UI.
  • Consider providing an accessible label (for example via <title> and aria-labelledby, or via alt/aria-hidden attributes) depending on the usage context.

🧪 Development & testing

Useful commands (from packages/svg-core):

npm run dev     # build in watch mode
npm run build   # production build
npm test        # run tests (vitest)
npm run lint    # eslint + tsc

Tests use vitest and jsdom to simulate a DOM environment.

🤝 Contributing

  • Open an issue or a pull request on the repository: https://github.com/pplancq/svg-tools
  • Respect linting rules (npm run lint) and tests (npm test) before submitting.

📚 Resources & contact

  • Project: https://github.com/pplancq/svg-tools
  • Project site: https://pplancq.github.io/svg-tools/
  • Bugs / requests: https://github.com/pplancq/svg-tools/issues

📜 License

MIT