DEV Community

Cover image for From SVG to PNG: Copy & Download with Konva.js
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on • Edited on

From SVG to PNG: Copy & Download with Konva.js

Hello, I'm Maneshwar. I'm working on git-lrc: a Git hook for Checking AI generated code.

When you’re building an SVG icon library, one essential feature is the ability to export icons as PNGs.

PNGs are still the go-to format for many developers and designers because they’re universally supported and easy to drop into apps, documents, or design tools.

Instead of relying on server-side conversion or external graphics editors, we can do this entirely in the browser.

Enter Konva.js — a 2D canvas framework that makes rendering, transforming, and exporting graphics simple.

In our project, we implemented two handy features for our icon library:

  • Copy as PNG → places the PNG version of an SVG directly into the clipboard.
  • Download as PNG → lets users pick a size (32px → 512px) and download instantly.

👉 Full implementation here:

FreeDevTools

Why Konva.js?

You could technically draw an SVG into a <canvas> using the Canvas API.

But Konva provides a much more developer-friendly abstraction with:

  • Stages & Layers → a clean way to structure drawings.
  • Image.fromURL → easy image & SVG loading.
  • Stage.toDataURL → export to PNG or JPEG in one call.
  • Built-in transformations (scale, position, rotate) without writing boilerplate math.

This makes it perfect for icon rendering, where precision and quality matter.

Setting up a Konva Stage

The first step in our flow is to create a hidden Konva stage. Since the user doesn’t need to see the rendering process, we mount it off-screen:

const stage = new Konva.Stage({
  container: container,  // hidden temporary <div>
  width: size,
  height: size,
});

const layer = new Konva.Layer();
stage.add(layer);
Enter fullscreen mode Exit fullscreen mode

📖 Konva Stage docs
📖 Konva Layer docs

Think of a Stage like a root canvas, and a Layer like a transparent sheet you can draw on.

You can stack multiple layers if needed.

Loading the SVG

Next, we load the raw SVG string into the Konva stage.

Since Konva works with image nodes, we first convert the SVG into a data URL:

const svgDataUrl = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svgData);

Konva.Image.fromURL(svgDataUrl, (imageNode) => {
  // add imageNode to layer
});
Enter fullscreen mode Exit fullscreen mode

📖 Konva.Image.fromURL docs

Tip: make sure your SVG string has an xmlns attribute (xmlns="http://www.w3.org/2000/svg"). Without it, some browsers may fail to render.

Scaling & Centering the Icon

Icons rarely come in perfect square ratios.

If we just stretch them, they’ll look distorted.

To keep the aspect ratio intact, we calculate it and fit the image to ~80% of the stage:

const imageAspect = imageNode.width() / imageNode.height();

if (imageAspect > 1) {
  imageWidth = size * 0.8;
  imageHeight = imageWidth / imageAspect;
} else {
  imageHeight = size * 0.8;
  imageWidth = imageHeight * imageAspect;
}

imageNode.setAttrs({
  x: (size - imageWidth) / 2,
  y: (size - imageHeight) / 2,
  width: imageWidth,
  height: imageHeight,
});
Enter fullscreen mode Exit fullscreen mode

This way:

  • Wide icons scale down horizontally.
  • Tall icons scale down vertically.
  • Everything stays centered in the final PNG.

Exporting to PNG

The magic happens with Konva’s toDataURL method:

const dataURL = stage.toDataURL({
  mimeType: 'image/png',
  quality: 1,
  pixelRatio: 2, // High DPI export
});
Enter fullscreen mode Exit fullscreen mode

📖 Stage.toDataURL docs

At this point, we have a base64 PNG string. From here, we can:

  • Clipboard path → turn it into a Blob, wrap with ClipboardItem, and use navigator.clipboard.write().
  • Download path → create a temporary <a> link, set href = dataURL, and trigger a click().

That’s all it takes!

👉 Full code here:

  • Download PNG→ lets users select output resolution (32px–512px) and saves as PNG.

Wrap-Up

With just a few Konva primitives (Stage, Layer, Image.fromURL, Stage.toDataURL), you can transform raw SVG icons into beautiful, transparent PNGs right in the browser.

Benefits of this approach:

  • 100% client-side → no servers, no latency.
  • Supports clipboard + download workflows.
  • Maintains sharpness & transparency.
  • Easy to extend (you could add backgrounds, shapes, or transformations).

If you’re building tools around SVGs, Konva is a fantastic choice, flexible enough for full-blown drawing apps, but lightweight enoughfor simple export utilities like ours.

git-lrc
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.

⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Unlimited AI Code Reviews That Run on Commit

git-lrc logo

git-lrc

Free, Unlimited AI Code Reviews That Run on Commit


git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
  • 🔗 Why git? Git is universal. Every editor, every IDE, every AI…




Top comments (0)