SVG Illustration skill for Codex

Hand-written SVG art you can still edit later. Codex draws illustrations directly in SVG with a stated style and a palette taken from your tokens, composes on a viewBox grid, and writes paths, symbols and gradients a developer can still edit by hand. Art themes through CSS custom properties for dark mode, patterns tile without visible edges, animation respects reduced motion, and SVGO output is checked so viewBox, titles and referenced IDs survive.

  • Design & UX
  • $svg-illustration
  • 180 lines
  • 2 files
  • ~1,950 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- svg-illustration

Installs to ~/.agents/skills/svg-illustration/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $svg-illustration, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Hand-authors SVG illustrations, spot graphics, hero art, backgrounds and repeating patterns - composition on a viewBox grid, path commands and arcs written deliberately, reuse with defs, symbol and use, gradients, clipPath and mask, theming with currentColor and CSS custom properties, optional CSS animation with reduced-motion fallbacks, SVGO optimisation and accessible markup. Use when asked to draw an illustration, empty-state graphic, decorative background, pattern or animated SVG in code rather than in a drawing app.

Use it when

  • A screen needs a spot illustration or empty-state graphic drawn in code
  • You want a decorative background or tiling pattern as SVG
  • An illustration must follow theme tokens and switch with dark mode
  • An existing SVG illustration is bloated and needs a clean rewrite

Use something else when

How to check the result

The SVG renders correctly at its smallest and largest sizes in light and dark themes, two copies on one page do not interfere, and reduced-motion emulation stops all animation.

The mistake it prevents

Reusing generic IDs like gradient1 in several inline SVGs, so one illustration's gradient silently paints another on the same page.

~/.agents/skills/svg-illustration/SKILL.md

--- name: svg-illustration description: Hand-authors SVG illustrations, spot graphics, hero art, backgrounds and repeating patterns - composition on a viewBox grid, path commands and arcs… license: MIT ---

A good code-drawn illustration has a clear focal point, a limited palette pulled from the product’s tokens, consistent stroke and corner language, and markup small and tidy enough that another developer can edit it by hand. It themes with CSS and degrades gracefully when motion is off.

Workflow

  • Define the job: where it appears, size range, what it should communicate.
  • Pick a style and palette from the product’s tokens (3-5 colors).
  • Block out composition with simple shapes on the viewBox grid.
  • Refine shapes with paths; add detail only where the eye lands.
  • Factor repeats into <defs>, theme with CSS variables.
  • Optimise, add accessibility markup, check at smallest and largest sizes.

1. Brief and style

Placement: empty state on Projects page, 160-240px wide, light and dark themes
Message: "nothing here yet, but it is easy to start"
Style: flat shapes, 2px strokes, 4px corner radius, no outlines on fills
Palette: --illus-bg, --illus-primary (brand-500), --illus-accent, --illus-line (neutral-700)

Pick one style and stay inside it:

StyleTraitsGood for
Flat geometricPrimitives, no strokes, 2-3 tones per objectEmpty states, onboarding
Line artSingle stroke weight, round caps/joins, minimal fillsDocs, feature explainers
Isometric30-degree axes, three tones per face (top light, left mid, right dark)Architecture or product overviews
Abstract blobs and gradientsOrganic curves, soft gradientsHero backgrounds

2. Canvas and composition

  • Choose a viewBox matching the aspect ratio of the slot, in round numbers (0 0 240 160). Work on an 8-unit grid; snap key points to it.
  • Place the focal object off-centre (rule of thirds) and give it the highest contrast.
  • Ground objects with a soft shadow ellipse or base shape; floating objects look pasted.
  • Keep a margin of about 8% of the width empty so the art does not touch its container.

3. Paths you will write by hand

CommandMeaningUse for
M x yMoveStart each subpath
L, H, VLinesHard edges
C x1 y1 x2 y2 x yCubic BezierOrganic curves
S x2 y2 x ySmooth cubic (reflects previous control)Chained curves without kinks
Q, TQuadraticSimple arcs, waves
A rx ry rot large sweep x yElliptical arcRounded corners, circles in paths, pie slices
ZCloseFills that should close

Lowercase is relative to the current point, which makes repeated shapes easier to move. For smooth curves, keep the incoming and outgoing control points collinear with the anchor. Use <rect rx>, <circle>, <ellipse> and <line> instead of paths when the shape is primitive; they stay readable.

4. Structure and reuse

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 160" role="img" aria-labelledby="ep-t">
  <title id="ep-t">Empty project board with a plus card</title>
  <style>
    .ep-bg { fill: var(--illus-bg, #eef2ff); }
    .ep-shadow { fill: var(--illus-shadow, #e2e8f0); }
    .ep-surface { fill: var(--illus-surface, #fff); stroke: var(--illus-line, #334155); stroke-width: 2; }
    .ep-muted { fill: var(--illus-muted, #cbd5e1); }
    .ep-primary { fill: var(--illus-primary, #4f46e5); }
  </style>
  <defs>
    <symbol id="ep-card" viewBox="0 0 56 40">
      <rect class="ep-surface" x="1" y="1" width="54" height="38" rx="4"/>
      <rect class="ep-muted" x="8" y="10" width="28" height="4" rx="2"/>
      <rect class="ep-muted" x="8" y="20" width="40" height="4" rx="2"/>
    </symbol>
  </defs>
  <rect class="ep-bg" width="240" height="160"/>
  <ellipse class="ep-shadow" cx="120" cy="136" rx="84" ry="8"/>
  <use href="#ep-card" x="40" y="56" width="56" height="40"/>
  <use href="#ep-card" x="104" y="44" width="56" height="40" opacity=".6"/>
  <g transform="translate(168 64)">
    <rect class="ep-primary" width="40" height="40" rx="8"/>
    <path d="M20 12v16M12 20h16" stroke="#fff" stroke-width="3" stroke-linecap="round"/>
  </g>
</svg>
  • Group related shapes in <g> with a meaningful id or comment; translate groups instead of editing every coordinate.
  • href on <use> works in all current browsers; xlink:href is only needed for old tooling.
  • IDs and <style> rules inside inline SVG are global in the page. Prefix both (ep-) when several inline SVGs can appear together, or one SVG’s rules will paint another.

5. Theming

  • Inline SVG can use currentColor and CSS custom properties, as in the example, so dark mode works by redefining variables. Put var() in CSS (a <style> block or style attribute) rather than in presentation attributes, and give fallbacks.
  • SVG loaded via <img> or CSS background-image cannot read page CSS variables; bake colors in or ship light and dark files with <picture> and prefers-color-scheme.
  • In dark mode, swap rather than invert: lighter lines, darker surfaces, slightly lower saturation for large fills.

6. Patterns and backgrounds

<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%">
  <defs>
    <pattern id="dots" width="16" height="16" patternUnits="userSpaceOnUse">
      <circle cx="2" cy="2" r="1.5" fill="currentColor" opacity=".25"/>
    </pattern>
  </defs>
  <rect width="100%" height="100%" fill="url(#dots)"/>
</svg>

For CSS backgrounds, URL-encode the SVG (# becomes %23) in a data URI, or reference a file. Hide tile edges by letting shapes that cross one edge reappear on the opposite edge (draw them twice, offset by the tile size).

7. Animation (optional)

Animate transform and opacity with CSS; set transform-box: fill-box so transform-origin refers to the shape itself:

.float { animation: float 4s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes float { 50% { transform: translateY(-4px); } }
@media (prefers-reduced-motion: reduce) { .float { animation: none; } }

Line-drawing effect: set stroke-dasharray and stroke-dashoffset to the path length (pathLength="1" on the path lets you use 1 instead of measuring). Avoid SMIL for anything important; CSS is easier to control and to disable.

Optimise and ship

npx svgo illus.svg -o illus.min.svg --multipass --precision 2   # needs network on first run

Check that optimisation kept viewBox, <title>, and the IDs your CSS or <use> references. Inline SVGs used as React components: convert attributes to camelCase (strokeWidth) or use SVGR.

Accessibility

  • Meaningful illustration: role="img" plus <title> (and aria-labelledby), with a short description of what it shows.
  • Decorative: aria-hidden="true" and focusable="false", or <img alt="">.
  • Never put essential information only in the illustration.

Gotchas

  • Strokes scale with the viewBox. If the SVG is shown at very different sizes and stroke weight must stay constant, use vector-effect="non-scaling-stroke".
  • Huge path data from tracing tools is unmaintainable. Redraw with primitives.
  • Filters (feGaussianBlur, feDropShadow) are expensive when animated or used over large areas; use them sparingly, or pre-blur shapes with gradients.
  • Text in illustrations will not be translated and may lack its font; avoid it, or keep it as HTML outside the SVG.

Verification

  • Render in a browser at the smallest and largest intended sizes, light and dark theme.
  • Two copies on one page do not interfere (unique IDs).
  • File under about 10 KB for spot illustrations after SVGO; inspect anything larger.
  • Reduced-motion emulation (DevTools Rendering panel) stops all animation.

Related: logos and marks in $svg-logo-design; UI icon sets in $icon-systems; algorithmic or randomised art in $generative-art.

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "SVG Illustration"
  short_description: "Hand-written SVG art you can still edit later"
  default_prompt: "$svg-illustration Draw an SVG empty-state illustration for the projects page that works in dark mode"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc