Export design assets from Adobe XD at the correct format, resolution, and compression settings for production — SVG icons optimized with SVGO, retina-ready PNG images, and PDF assets for print, all from the Export panel.
Exporting assets from Adobe XD is a core part of the design-to-code workflow. Icons, illustrations, product images, and decorative graphics all need to be exported from XD at the correct format and resolution before developers can use them.
Poor asset export choices — wrong format, missing resolutions, unoptimized SVGs — create performance problems in production. A single oversized PNG where an optimized SVG was needed can add 50KB to a page load.
This lesson covers the complete XD export workflow: selecting the right format for each asset type, exporting at correct densities for Retina displays, and optimizing assets before committing them to the codebase.
The Export panel in XD is accessible from File → Export → Selected or by right-clicking any element and choosing Export.
Export workflow:
Format options in XD export:
SVG — for icons, logos, illustrations, and any vector graphic:
PNG — for raster images, photos with transparent backgrounds, screenshots:
JPEG — for photographs without transparency:
PDF — for print assets, high-fidelity documents:
Export scale options and their uses:
11x → standard displays (CSS pixel = physical pixel)
22x → Retina / HiDPI (most modern laptops and phones)
33x → highest-density phones (iPhone 15 Pro Max = 3x)
40.5x → thumbnail generationSVG is the preferred format for all vector assets — icons, logos, illustrations, and simple graphics. XD's SVG export includes unnecessary metadata, inline styles, and Adobe-specific attributes that must be cleaned up before production use.
XD SVG export sample (raw, unoptimized):
1<?xml version="1.0" encoding="utf-8"?>
2<!-- Generator: Adobe XD 57.1.12.2 -->
3<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
4 width="24" height="24" viewBox="0 0 24 24">
5 <defs>
6 <style>.cls-1{fill:none;}.cls-2{fill:#2563eb;}</style>
7 </defs>
8 <rect id="Background" class="cls-1" width="24" height="24"/>
9 <path id="icon_path" class="cls-2"
10 d="M12,2A10,10,0,1,0,22,12,10.011,10.011,0,0,0,12,2Zm1,17H11V11h2Zm0-8H11V9h2Z"/>
11</svg>Same SVG after SVGO optimization:
1<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
2 <path fill="#2563eb" d="M12 2a10 10 0 1 0 0 20A10 10 0 0 0 12 2m1 17h-2v-6h2Zm0-8h-2V9h2Z"/>
3</svg>Running SVGO:
1# Install SVGO globally
2npm install -g svgo
3
4# Optimize a single file
5svgo icon-info.svg -o icon-info.optimized.svg
6
7# Optimize all SVGs in a directory
8svgo -r ./icons/ -o ./icons-optimized/
9
10# Optimize in place (replaces original)
11svgo icon-info.svg
12
13# With a config file for consistent settings
14svgo --config svgo.config.js icon-info.svgSVGO config for design system icons (svgo.config.js):
1module.exports = {
2 plugins: [
3 { name: 'preset-default' },
4 { name: 'removeViewBox', active: false }, // keep viewBox for scaling
5 { name: 'removeDimensions', active: true }, // remove width/height (set by CSS)
6 { name: 'removeComments', active: true },
7 { name: 'removeDesc', active: true },
8 { name: 'removeTitle', active: false }, // keep title for accessibility
9 { name: 'convertColors', params: { shorthex: true } },
10 { name: 'cleanupIds', active: true },
11 {
12 name: 'removeAttrs',
13 params: {
14 attrs: ['data-name', 'id'] // remove XD layer names
15 }
16 }
17 ]
18};For React SVG components, use SVGR:
1# Install SVGR
2npm install -D @svgr/cli
3
4# Convert all SVGs to React components
5svgr --jsx-runtime automatic --no-dimensions icons/ --out-dir src/icons/Generated React SVG component:
1// src/icons/InfoCircle.tsx (auto-generated by SVGR)
2import type { SVGProps } from 'react';
3
4export function InfoCircle(props: SVGProps<SVGSVGElement>) {
5 return (
6 <svg viewBox="0 0 24 24" aria-hidden="true" {...props}>
7 <path d="M12 2a10 10 0 1 0 0 20A10 10 0 0 0 12 2m1 17h-2v-6h2Zm0-8h-2V9h2Z" />
8 </svg>
9 );
10}For raster images (photographs, screenshots, complex illustrations), export at multiple resolutions for Retina display support. XD makes this straightforward — check multiple scale checkboxes before exporting.
Exporting at multiple scales from XD:
Using exported files in HTML with srcset:
1<!-- Standard responsive image with srcset -->
2<img
3 src="course-thumbnail.png"
4 srcset="
5 course-thumbnail.png 1x,
6 [email protected] 2x,
7 [email protected] 3x
8 "
9 width="280"
10 height="160"
11 alt="CSS Mastery course — abstract geometric design in blue and white"
12 loading="lazy"
13>
14
15<!-- With sizes attribute for responsive images -->
16<img
17 src="hero-image.png"
18 srcset="
19 hero-image.png 480w,
20 [email protected] 960w,
21 [email protected] 1440w
22 "
23 sizes="(max-width: 48rem) 100vw, 50vw"
24 width="720"
25 height="480"
26 alt="Developer working on code with a design file open"
27 loading="eager"
28 fetchpriority="high"
29>Modern format alternatives (better than PNG for photos):
1<!-- Use <picture> for next-gen format support -->
2<picture>
3 <source
4 type="image/avif"
5 srcset="
6 course-thumbnail.avif 1x,
7 [email protected] 2x
8 "
9 >
10 <source
11 type="image/webp"
12 srcset="
13 course-thumbnail.webp 1x,
14 [email protected] 2x
15 "
16 >
17 <!-- PNG fallback for older browsers -->
18 <img
19 src="course-thumbnail.png"
20 srcset="[email protected] 2x"
21 width="280"
22 height="160"
23 alt="CSS Mastery course"
24 loading="lazy"
25 >
26</picture>Converting XD PNG exports to WebP/AVIF:
1# Using sharp (Node.js)
2npm install -g sharp-cli
3sharp -i hero.png -o hero.webp --webp
4sharp -i hero.png -o hero.avif --avif
5
6# Using cwebp (Google)
7cwebp -q 80 hero.png -o hero.webp
8
9# Batch conversion with imagemin
10npm install imagemin imagemin-webp imagemin-avifMost XD design systems organize icons as a component grid — a frame containing individual icon components named 'icon/arrow-right', 'icon/check', 'icon/x', etc. Exporting an entire icon set efficiently requires batch export.
Recommended XD icon export workflow:
XD names SVG files using the layer name — 'icon/arrow-right' exports as 'icon-arrow-right.svg'. Clean the filenames:
1# Remove 'icon-' prefix and rename to PascalCase for React
2ls src/assets/icons/
3# icon-arrow-right.svg, icon-check.svg, icon-x.svg, icon-menu.svg
4
5# After SVGO optimization and SVGR conversion:
6ls src/icons/
7# ArrowRight.tsx, Check.tsx, X.tsx, Menu.tsxOrganizing icon components in a React icon library:
1// src/icons/index.ts — barrel export
2export { ArrowRight } from './ArrowRight';
3export { Check } from './Check';
4export { X } from './X';
5export { Menu } from './Menu';
6
7// Usage in components:
8import { ArrowRight, Check } from '@/icons';
9
10function StatusBadge({ status }: { status: 'pass' | 'fail' }) {
11 return (
12 <span className="badge">
13 {status === 'pass'
14 ? <Check aria-hidden="true" className="icon" />
15 : <X aria-hidden="true" className="icon" />}
16 <span>{status === 'pass' ? 'Passed' : 'Failed'}</span>
17 </span>
18 );
19}CSS sizing for SVG icon components:
1/* Icons should inherit size from the parent font-size */
2.icon {
3 width: 1em; /* scales with font-size of parent */
4 height: 1em;
5 flex-shrink: 0; /* prevents squishing in flex containers */
6}
7
8/* Specific size tokens */
9.icon-sm { width: 1rem; height: 1rem; } /* 16px */
10.icon-md { width: 1.25rem; height: 1.25rem; } /* 20px */
11.icon-lg { width: 1.5rem; height: 1.5rem; } /* 24px */
12.icon-xl { width: 2rem; height: 2rem; } /* 32px */
13
14/* Fill color inherits from parent for easy theming */
15svg.icon {
16 fill: currentColor; /* inherits text color */
17}Exporting a 24-icon set from XD, running SVGO optimization, converting with SVGR, and building a typed React icon component system.
1#!/bin/bash
2# Complete icon export pipeline from XD
3
4# Step 1: After exporting SVGs from XD to /raw-icons/
5# Run SVGO optimization on all files
6svgo -r ./raw-icons/ -o ./optimized-icons/ --config svgo.config.js
7
8# Step 2: Run SVGR to convert SVGs to React components
9npx @svgr/cli \
10 --jsx-runtime automatic \
11 --no-dimensions \
12 --typescript \
13 --title-prop \
14 --desc-prop \
15 ./optimized-icons/ \
16 --out-dir ./src/icons/
17
18# Step 3: Generated TypeScript component (src/icons/ArrowRight.tsx)
19# (Shown below for illustration — auto-generated by SVGR)
20
21# --- TypeScript React Icon Component ---
22# The SVGR output, cleaned and typed:
23
24# interface IconProps extends SVGProps<SVGSVGElement> {
25# title?: string; // accessible name for non-decorative icons
26# titleId?: string; // for aria-labelledby
27# className?: string;
28# }
29
30# export const ArrowRight = ({ title, titleId, ...props }: IconProps) => (
31# <svg
32# viewBox="0 0 24 24"
33# aria-hidden={!title} // hide from a11y tree if no title
34# aria-labelledby={titleId} // link to title if provided
35# fill="currentColor"
36# {...props}
37# >
38# {title && <title id={titleId}>{title}</title>}
39# <path d="M5 12h14M12 5l7 7-7 7" stroke-width="2" stroke-linecap="round"/>
40# </svg>
41# );
42
43// src/icons/index.ts — auto-generated barrel export
44export * from './ArrowRight';
45export * from './Check';
46export * from './ChevronDown';
47export * from './X';
48export * from './Menu';
49export * from './BookOpen';
50export * from './Star';
51export * from './User';
52export * from './Lock';
53export * from './Unlock';
54export * from './Play';
55export * from './Pause';
56
57// CSS for icons in src/styles/icons.css
58.icon {
59 display: inline-block;
60 fill: currentColor;
61 flex-shrink: 0;
62 vertical-align: middle;
63 width: 1.25rem; /* default: 20px = icon-md */
64 height: 1.25rem;
65}
66
67.icon-sm { width: 1rem; height: 1rem; } /* 16px */
68.icon-md { width: 1.25rem; height: 1.25rem; } /* 20px */
69.icon-lg { width: 1.5rem; height: 1.5rem; } /* 24px */
70.icon-xl { width: 2rem; height: 2rem; } /* 32px */
71
72// Usage examples:
73import { Play, BookOpen, Star, Lock } from '@/icons';
74import '@/styles/icons.css';
75
76// Decorative icon (aria-hidden by default)
77<Play className="icon icon-md" aria-hidden="true" />
78
79// Meaningful icon with accessible name
80<Lock
81 className="icon icon-sm"
82 title="Course locked — purchase to unlock"
83 titleId="lock-123"
84 aria-labelledby="lock-123"
85/>The pipeline runs automatically: XD exports raw SVGs → SVGO removes metadata and unused attributes → SVGR converts to typed React components with title/titleId props for accessibility. The title prop is the key accessibility feature — when provided, SVGR adds a <title> element inside the SVG and sets aria-labelledby, making the icon meaningful to screen readers. When not provided (decorative usage), the icon has aria-hidden=true by default. The fill: currentColor CSS rule means the icon color always matches the parent's text color, so theming and dark mode work automatically without any prop changes.
The next lesson covers XD Co-editing — how multiple designers collaborate in real-time on the same XD file, and how this workflow affects developer handoff timing and file version management.
Your progress is saved in this browser, on this device only.