Optimize SVG images

SVG images use XML-based markup to describe vector graphics. Optimize SVG markup using SVGO.

Face with waiting expression Nothing to see yet!

Loading takeymakey...
TakeyMakey code
Want this tool to do something else? Edit the code below and make it do whatever you want.
import svgo from "https://cdn.jsdelivr.net/npm/svgo@3.2.0/dist/svgo.browser.js"

export const take = [
  { type: "code", label: "Source SVG" },
  { type: "toggle", label: "Multipass" },
  { type: "toggle", label: "Pretty" },
  { type: "dropdown", label: "Indent", options: [2, 4] },
  {
    type: "dropdown",
    label: "Float precision",
    value: 1,
    options: [0, 1, 2, 3, 4, { label: "Ignore", value: 14 }],
  },
  {
    type: "dropdown",
    label: "Transform precision",
    value: 1,
    options: [0, 1, 2, 3, 4, { label: "Ignore", value: 14 }],
  },
  { type: "toggle", label: "Remove groups", value: true },
  { type: "toggle", label: "Merge paths", value: true },
]

export const make = ([
  svg,
  multipass,
  pretty,
  indent,
  floatPrecision,
  transformPrecision,
  collapseGroups,
  mergePaths,
]) => {
  if (!svg) return

  const overrides = {}

  const plugins = [
    "removeDoctype",
    "removeXMLProcInst",
    "removeComments",
    "removeMetadata",
    "removeEditorsNSData",
    "cleanupAttrs",
    "mergeStyles",
    "inlineStyles",
    "minifyStyles",
    "removeUselessDefs",
    "cleanupNumericValues",
    "convertColors",
    "removeUnknownsAndDefaults",
    "removeNonInheritableGroupAttrs",
    "removeUselessStrokeAndFill",
    "removeViewBox",
    "cleanupEnableBackground",
    "removeHiddenElems",
    "removeEmptyText",
    "convertShapeToPath",
    "moveElemsAttrsToGroup",
    "moveGroupAttrsToElems",
    "collapseGroups",
    "convertPathData",
    "convertEllipseToCircle",
    "convertTransform",
    "removeEmptyAttrs",
    "removeEmptyContainers",
    "mergePaths",
    "removeUnusedNS",
    "sortAttrs",
    "sortDefsChildren",
    "removeTitle",
    "removeDesc",
  ]

  plugins.forEach((key) => {
    overrides[key] = { floatPrecision, transformPrecision }
  })

  if (!collapseGroups) overrides.collapseGroups = false
  if (!mergePaths) overrides.mergePaths = false

  const value = svgo.optimize(svg, {
    multipass,
    js2svg: { indent, pretty },
    plugins: [
      {
        name: "preset-default",
        params: {
          overrides,
        },
      },
    ],
  }).data

  const scale = value.length / svg.length
  const message = `The new SVG is ${
    scale === 1
      ? "equal to"
      : +Math.abs((1 - scale) * 100).toFixed(1) +
        "% " +
        (scale < 1 ? "smaller" : "larger") +
        " than"
  }  the source image.`

  return [
    {
      label: "Optimized SVG",
      type: "code",
      value,
    },
    {
      type: "image",
      label: "Preview",
      value,
      format: "svg",
    },
    {
      label: "Optimized SVG",
      type: "status",
      value: scale < 1,
      message,
    },
  ]
}