Back to BlogTechnical

SVG Path Commands: Complete Visual Guide to the d Attribute

SVG Genie Team15 min read

You open an SVG file and see this:

<path d="M10 80 Q 95 10 180 80 T 350 80" fill="none" stroke="black"/>

What does any of that mean?

The d attribute contains path commands—a mini language that tells the browser how to draw shapes. Once you understand it, you can read, write, and debug any SVG path. This guide breaks down every command with visual examples.

The Basics: How Path Commands Work

Every path command has a letter followed by coordinates. The letter defines what to draw, the coordinates define where.

M 10 20    → Move to point (10, 20)
L 50 60    → Draw line to point (50, 60)

Uppercase vs lowercase:

  • Uppercase (M, L, C) = absolute coordinates from origin (0,0)
  • Lowercase (m, l, c) = relative to current position
<!-- Absolute: go to exact point (100, 50) -->
<path d="M 0 0 L 100 50"/>

<!-- Relative: move 100 right and 50 down from current position -->
<path d="M 0 0 l 100 50"/>

Both draw the same line if starting from (0,0), but relative commands are easier when building complex shapes piece by piece.

Command Reference: Every SVG Path Command

M / m — Move To

Move the pen without drawing.

M x y     (absolute)
m dx dy   (relative)

Every path starts with M. It's like lifting your pen and placing it somewhere new.

<svg viewBox="0 0 100 100">
  <!-- Start at (10, 10), draw nothing yet -->
  <path d="M 10 10 L 90 90" stroke="black" fill="none"/>
</svg>

Multiple M commands create separate subpaths (useful for shapes with holes):

<!-- Square with a square hole -->
<path d="M 10 10 L 90 10 L 90 90 L 10 90 Z
         M 30 30 L 70 30 L 70 70 L 30 70 Z"
      fill-rule="evenodd"/>

L / l — Line To

Draw a straight line to a point.

L x y     (absolute)
l dx dy   (relative)

The most basic drawing command:

<svg viewBox="0 0 100 100">
  <path d="M 10 10 L 90 10 L 90 90 L 10 90 L 10 10"
        stroke="black" fill="none"/>
</svg>

This draws a square: move to (10,10), line to (90,10), line to (90,90), line to (10,90), line back to start.

H / h — Horizontal Line

Draw a horizontal line.

H x    (absolute: go to x, keep current y)
h dx   (relative: move dx horizontally)

Shorthand for horizontal movement:

<!-- These are equivalent -->
<path d="M 10 50 L 90 50"/>
<path d="M 10 50 H 90"/>
<path d="M 10 50 h 80"/>

V / v — Vertical Line

Draw a vertical line.

V y    (absolute: go to y, keep current x)
v dy   (relative: move dy vertically)
<!-- Draw a vertical line down -->
<path d="M 50 10 V 90"/>

H and V are useful for rectangles, grids, and geometric shapes where you're moving along axes.

Z / z — Close Path

Draw a line back to the starting point.

Z   (no parameters)
z   (identical to Z)

Closes the current subpath by drawing a straight line to the most recent M command:

<!-- Triangle, closed with Z -->
<path d="M 50 10 L 90 90 L 10 90 Z" fill="blue"/>

<!-- Without Z, there'd be a gap -->
<path d="M 50 10 L 90 90 L 10 90" fill="blue"/>

Always use Z to close shapes—it ensures perfectly connected corners, which matters for fills and strokes.

Curve Commands: Where It Gets Interesting

Straight lines are easy. Curves are where SVG paths become powerful.

Q / q — Quadratic Bézier Curve

A curve with one control point.

Q cx cy, x y    (absolute)
q dcx dcy, dx dy   (relative)

The control point (cx, cy) acts like a magnet, pulling the curve toward it:

<svg viewBox="0 0 200 100">
  <!-- Curve from (10, 90) to (190, 90), control point at (100, 10) -->
  <path d="M 10 90 Q 100 10, 190 90" stroke="black" fill="none"/>

  <!-- Visualize the control point -->
  <circle cx="100" cy="10" r="3" fill="red"/>
  <line x1="10" y1="90" x2="100" y2="10" stroke="red" stroke-dasharray="2"/>
  <line x1="100" y1="10" x2="190" y2="90" stroke="red" stroke-dasharray="2"/>
</svg>

When to use Q:

  • Simple curves like arches
  • Smooth corners
  • When you need a gentle bend with minimal complexity

T / t — Smooth Quadratic Curve

Continue a quadratic curve smoothly.

T x y    (absolute)
t dx dy  (relative)

T automatically calculates the control point by reflecting the previous control point:

<svg viewBox="0 0 400 100">
  <!-- Wave pattern using Q followed by T -->
  <path d="M 10 50 Q 50 10, 100 50 T 200 50 T 300 50 T 400 50"
        stroke="black" fill="none"/>
</svg>

This creates a smooth wave. Each T continues the curve naturally without needing to specify control points.

C / c — Cubic Bézier Curve

A curve with two control points.

C cx1 cy1, cx2 cy2, x y    (absolute)
c dcx1 dcy1, dcx2 dcy2, dx dy   (relative)

Two control points give you more control over the curve shape:

<svg viewBox="0 0 200 100">
  <!-- S-curve using two control points -->
  <path d="M 10 90 C 40 10, 160 10, 190 90" stroke="black" fill="none"/>

  <!-- Control points -->
  <circle cx="40" cy="10" r="3" fill="red"/>
  <circle cx="160" cy="10" r="3" fill="blue"/>
</svg>

Cubic vs Quadratic:

| Quadratic (Q) | Cubic (C) | |---------------|-----------| | 1 control point | 2 control points | | Simpler, smaller file | More control over shape | | Symmetric curves only | Asymmetric curves possible | | Good for simple arcs | Good for complex curves |

Most design tools export cubic curves because they're more flexible.

S / s — Smooth Cubic Curve

Continue a cubic curve smoothly.

S cx2 cy2, x y    (absolute)
s dcx2 dcy2, dx dy   (relative)

Like T for quadratic curves, S reflects the previous control point for smooth continuation:

<svg viewBox="0 0 300 100">
  <!-- Smooth wave with cubic curves -->
  <path d="M 10 50 C 30 10, 70 10, 100 50 S 170 90, 200 50 S 270 10, 300 50"
        stroke="black" fill="none"/>
</svg>

You only specify the second control point; the first is calculated automatically.

A / a — Elliptical Arc

Draw an arc from an ellipse.

A rx ry rotation large-arc sweep x y    (absolute)
a rx ry rotation large-arc sweep dx dy  (relative)

The most complex command. Parameters:

  • rx, ry — ellipse radii
  • rotation — ellipse rotation in degrees
  • large-arc — 0 for small arc, 1 for large arc
  • sweep — 0 for counterclockwise, 1 for clockwise
  • x, y — end point
<svg viewBox="0 0 200 100">
  <!-- Simple circular arc -->
  <path d="M 20 50 A 30 30 0 0 1 80 50" stroke="black" fill="none"/>

  <!-- Same endpoints, large arc flag = 1 -->
  <path d="M 120 50 A 30 30 0 1 1 180 50" stroke="blue" fill="none"/>
</svg>

The four possible arcs between any two points (due to large-arc and sweep flags):

<svg viewBox="0 0 200 200">
  <!-- All four arcs between same two points -->
  <path d="M 50 100 A 40 40 0 0 0 150 100" stroke="red"/>    <!-- small, ccw -->
  <path d="M 50 100 A 40 40 0 0 1 150 100" stroke="green"/>  <!-- small, cw -->
  <path d="M 50 100 A 40 40 0 1 0 150 100" stroke="blue"/>   <!-- large, ccw -->
  <path d="M 50 100 A 40 40 0 1 1 150 100" stroke="orange"/> <!-- large, cw -->
</svg>

When to use A:

  • Pie charts and donut charts
  • Rounded corners (though border-radius is easier for rectangles)
  • Circular progress indicators
  • Any arc that's part of an ellipse

Practical Examples

Drawing a Heart

<svg viewBox="0 0 100 100">
  <path d="M 50 88
           C 20 68, 5 40, 25 20
           C 40 5, 50 15, 50 30
           C 50 15, 60 5, 75 20
           C 95 40, 80 68, 50 88
           Z"
        fill="red"/>
</svg>

The heart uses four cubic curves meeting at points.

Drawing a Star

<svg viewBox="0 0 100 100">
  <path d="M 50 5
           L 61 40
           L 98 40
           L 68 60
           L 79 95
           L 50 75
           L 21 95
           L 32 60
           L 2 40
           L 39 40
           Z"
        fill="gold"/>
</svg>

Stars are just lines connecting calculated points.

Smooth Squiggle

<svg viewBox="0 0 300 100">
  <path d="M 10 50
           Q 40 10, 75 50
           T 150 50
           T 225 50
           T 290 50"
        stroke="purple" stroke-width="3" fill="none"/>
</svg>

Using Q followed by T commands creates smooth, continuous waves.

Optimizing Path Data

Long path data increases file size. Optimization techniques:

1. Remove whitespace:

<!-- Before -->
<path d="M 10 20 L 30 40 L 50 60"/>

<!-- After -->
<path d="M10 20L30 40L50 60"/>

2. Use relative commands for repetitive patterns:

<!-- Absolute (longer) -->
<path d="M0 0 L10 10 L20 0 L30 10 L40 0"/>

<!-- Relative (shorter) -->
<path d="M0 0l10 10 10-10 10 10 10-10"/>

3. Use implicit line commands: After M, coordinates without a command letter are treated as L:

<!-- Explicit -->
<path d="M0 0 L10 10 L20 0"/>

<!-- Implicit -->
<path d="M0 0 10 10 20 0"/>

For automated optimization, use tools like SVG Minify or SVGO.

Reading Complex Paths

When you encounter a complex path, break it down:

<path d="M150 0 L75 200 L225 200 Z M150 50 L125 175 L175 175 Z"/>

Parse it step by step:

  1. M150 0 — Move to (150, 0)
  2. L75 200 — Line to (75, 200)
  3. L225 200 — Line to (225, 200)
  4. Z — Close path (triangle)
  5. M150 50 — New subpath at (150, 50)
  6. L125 175 — Line to (125, 175)
  7. L175 175 — Line to (175, 175)
  8. Z — Close path (inner triangle)

This creates a triangle with a triangular hole (like a warning icon).

Creating Paths: Tools and Methods

Design Software

  • Figma, Illustrator, Inkscape — Draw with pen tools, export as SVG
  • Great for complex illustrations
  • May produce verbose path data—optimize afterward

Code Generation

  • JavaScript libraries (D3.js, Paper.js) — Generate paths programmatically
  • Best for data visualization and generative art
  • See our guide on Generative SVG Art

AI Generation

Creating paths by hand is tedious. Modern AI tools can generate complete SVG graphics from text descriptions.

SVG Genie generates production-ready SVG paths from natural language. Instead of manually plotting bezier curves, describe what you want: "a minimalist mountain icon" or "an abstract wave pattern." The AI handles the path commands, outputting clean, optimized SVG code.

This is especially useful when you need custom graphics but don't want to spend hours in a vector editor.

Debugging Path Problems

Path Not Rendering

  • Check for valid syntax (missing coordinates, wrong command letters)
  • Ensure fill or stroke is set (default fill is black, default stroke is none)
  • Verify coordinates are within the viewBox

Unexpected Shape

  • Plot the path manually on graph paper
  • Use browser DevTools to inspect computed coordinates
  • Check for absolute vs relative command confusion

Jagged Curves

  • Not enough control points—try adding intermediate curves
  • Use SVG Editor to smooth paths
  • Consider if the curve type is appropriate (Q vs C)

Fill Looking Wrong

  • Check fill-rule property (nonzero vs evenodd)
  • Ensure paths are properly closed with Z
  • Verify winding direction for shapes with holes

Learn more about SVG troubleshooting in Why Is My SVG Blurry? and SVG Not Showing in Browser.

Key Takeaways

  1. M moves, L draws lines, Z closes — the fundamental commands
  2. Uppercase = absolute, lowercase = relative — know the difference
  3. Q for simple curves, C for complex ones — quadratic vs cubic bezier
  4. T and S continue curves smoothly — automatic control point reflection
  5. A for arcs — complex but essential for circular shapes
  6. Optimize for file size — remove whitespace, use relative commands, implicit lines

Understanding path commands gives you complete control over SVG shapes. Whether you're debugging exported files, hand-coding icons, or just trying to understand how vector graphics work, this knowledge is foundational.

Rather not write path commands by hand? SVG Genie generates complete SVG graphics—paths and all—from simple text descriptions. Describe your vision, get production-ready vector code.


Related Articles:

Create your own SVG graphics with AI

Describe what you need, get a production-ready vector in seconds. No design skills required.

Try SVG Genie Free

Ready to create your own vectors?

Start designing with AI-powered precision today.

Get Started Free