Generating SVG Graphics with AI for Technical Blogs

To generate precise, scalable technical diagrams for your blog, prompt an LLM to output SVG or Mermaid.js syntax rather than relying on pixel-based image generation. The result is graphics that are lightweight, resolution-independent, and fully accessible to search engines - qualities that raster images can never match.
Why SVG? The Case Against Raster Images for Technical Diagrams
When most bloggers need a diagram, they reach for a screenshot, a PNG export from a design tool, or a raster image generated by a text-to-image model. This habit is understandable but carries real costs that compound over time. A flowchart exported as PNG typically weighs between 100 KB and 400 KB depending on dimensions and compression. The same diagram described as SVG almost always lands between 5 KB and 20 KB. That is not a marginal difference - it is an order of magnitude, and it shows up directly in Core Web Vitals metrics like Largest Contentful Paint and Total Blocking Time, which Google uses as ranking signals.
Resolution independence is the second major advantage and one that matters increasingly as high-DPI displays become the default. A PNG that looks crisp on a 1080p monitor looks soft and blurry on a Retina or 4K screen because raster images are fixed-pixel grids. SVG is a mathematical description of shapes, so it renders at whatever resolution the display demands - pixel-perfect on a 96 dpi laptop, a 218 dpi iPhone, and a 320 dpi Samsung Galaxy alike. Once you start publishing SVG diagrams, you will never be satisfied with blurry PNGs again.
Accessibility and SEO follow naturally from the XML-based nature of SVG. The text nodes inside an SVG file - labels, annotations, axis titles - are real text that search engine crawlers can read and index. A screen reader can traverse them just as it traverses any other text on the page. A PNG is an opaque blob to both. If your diagrams contain keywords relevant to your topic, an SVG diagram contributes to your page’s semantic content in a way that a raster image simply cannot.
Finally, there is the dark mode problem that every technical blogger eventually encounters. Maintaining two versions of every diagram - one for light mode, one for dark - is tedious and error-prone. SVG eliminates this entirely. Because SVG elements accept CSS custom properties and the currentColor keyword, you can write a handful of CSS rules that make every diagram on your site automatically switch its color scheme when the user toggles dark mode. No JavaScript, no duplication, no maintenance burden.
Choosing the Right Format: SVG vs. Mermaid.js vs. React/JSX
Not all vector graphics are the same, and choosing the right format before you start prompting saves significant iteration time. The decision hinges on three questions: Is this a standard diagram type with a known structure? Does the diagram need to be interactive or data-driven? And how much raw SVG complexity is acceptable for your workflow?
Mermaid.js is the fastest path to publication for standard diagram types. Flowcharts, sequence diagrams, Gantt charts, entity-relationship diagrams, class diagrams, and state machines all have first-class Mermaid syntax. LLMs produce valid Mermaid code with high reliability because the syntax is compact, declarative, and well-represented in training data. The code is stored as plain text alongside your Markdown, which means it diffs cleanly in git and renders in GitHub previews without any additional tooling. For Hugo specifically, Mermaid integrates via a shortcode that injects the renderer JavaScript and wraps the diagram block - a one-time setup that pays dividends on every future post.
Raw SVG is necessary when you need something Mermaid cannot express: a custom architecture diagram showing the physical topology of a distributed system, an annotated screenshot with callout boxes, a custom icon, or any layout that does not fit neatly into Mermaid’s predefined diagram types. LLMs generate raw SVG most reliably when the diagram is composed of geometric primitives - rectangles, circles, lines, and text - rather than complex <path> elements with encoded coordinate data. For simple custom diagrams, raw SVG from an LLM is excellent. For highly intricate illustrations, quality degrades.
React/JSX components using D3.js, Recharts, or Nivo are the right choice when your diagram is data-driven or interactive - a live chart updated from an API, an explorable graph, or a visualization where the user can filter and drill down. This is genuinely powerful but it is also significant engineering overhead. For a Hugo blog using standard Markdown, it requires either an MDX pipeline or custom JavaScript injection. Reserve this approach for cases where interactivity is a genuine requirement, not just a nice-to-have.
The decision tree for any new diagram looks like this: if the diagram matches a standard type (flowchart, sequence, ER, Gantt, state machine) - use Mermaid. If the diagram is custom-shaped, geometrically simple, and static - use raw SVG. If the diagram is data-driven or must be interactive - use React/D3. When all three options feel like too much friction, Excalidraw, draw.io, or Figma remain excellent manual fallbacks for complex diagrams that justify the investment.
Prompting for Vector Semantics
Prompting an LLM to generate SVG or Mermaid code requires a different mental model than prompting it to write prose or generate a raster image. The key shift is moving from describing appearance to describing structure. An LLM is a text-prediction engine reasoning about symbolic relationships - it handles logical structure well. It does not have an internal model of visual space, so vague aesthetic prompts produce vague results.
The “describe structure, not appearance” principle plays out concretely: “a flowchart with 4 nodes representing Request, Validate, Process, and Respond, with sequential directed edges between them” produces much better output than “draw me a nice blue process diagram.” The first prompt gives the model something it can reason about symbolically. The second forces it to invent both the content and the visual style, and it will often get both wrong. Whenever possible, enumerate the elements explicitly: list the nodes, name the edges, specify which direction arrows point.
For raw SVG, constrain the output technically before you ask for it. Specify the viewBox dimensions so the diagram scales predictably. Request <text> elements with a standard system font rather than embedded font data, which inflates file size. Most importantly, ask the LLM to use currentColor for all stroke and fill values that should participate in dark mode theming. This single instruction eliminates the need to manually edit color values later. A template for this looks like:
Generate a raw SVG diagram with viewBox="0 0 800 400". Use only <rect>, <circle>, <line>,
<text>, and <g> elements - no complex <path> data. Use currentColor for all stroke and fill
attributes that should theme with the page. Use a standard sans-serif font for all text.
The diagram should show: [your structural description here].For Mermaid, the most effective prompts are those that supply the actual content rather than asking the LLM to invent it. Compare “generate a Mermaid sequence diagram for an OAuth 2.0 authorization code flow” with “generate a Mermaid sequence diagram showing the following steps: User requests /authorize, Server redirects to login page, User enters credentials, Server validates and issues auth code, Client exchanges auth code for access token, Server returns access token and refresh token.” The second prompt will produce code that is both syntactically correct and semantically accurate to your specific use case.
One technique that significantly improves output quality for complex diagrams is multi-shot prompting: before making your actual request, show the LLM one correct example of what a valid output looks like. Paste in a short working Mermaid diagram or a clean SVG snippet, then say “using the same structure and conventions, generate a new diagram for: [your request].” The model anchors on the syntactic patterns in your example and is far less likely to produce malformed output.
LLMs reliably struggle with complex <path d="..."> coordinate data. This is not surprising - path data is dense, position-dependent numerical sequences, and transformers are not geometry engines. Whenever a diagram prompt would require complex paths, restructure it to use primitives instead. A rounded rectangle is better expressed as <rect rx="8"> than as a bezier path. A diamond can be a <polygon> with four points. Reserve <path> for cases where you genuinely need curves that cannot be expressed another way.
Iterative Refinement of Generated Graphics
First-pass AI-generated SVG is rarely production-ready, and expecting otherwise leads to frustration. The right mental model is a “generate → review → refine” loop, typically requiring one to three iterations to reach publishable quality. Each iteration should target one specific problem rather than regenerating the entire diagram from scratch.
The most powerful technique for replicating an existing diagram is what might be called the “graphic-to-code” workflow: take a screenshot or photo of an existing diagram - from a whiteboard sketch, a printed paper, a slide deck, or another website - and upload it to a multimodal LLM alongside the instruction “reproduce this diagram as clean SVG using only geometric primitives and text elements.” This is remarkably effective for translating hand-drawn concepts into publishable vector graphics. The model extracts the structural relationships from the visual and expresses them in code, which you then refine. It sidesteps the blank-page problem entirely.
When iterating on a specific element, surgical precision beats wholesale regeneration. Instead of “regenerate the whole diagram,” say “the arrow between the Validate node and the Process node should be dashed, not solid” or “the background fill of the Error node should use --color-error instead of #ff4444.” Targeted incremental prompts preserve the parts of the diagram that are already correct while fixing only what needs to change. This approach also produces smaller diffs in version control, which makes reviewing changes easier.
Before embedding any AI-generated SVG in your blog, validate it. Paste the code into an online SVG viewer (SVG Viewer at svgviewer.dev is the most convenient) and check that it renders correctly. LLMs occasionally generate invalid attribute names, unclosed tags, or namespace issues that look syntactically plausible in a text editor but fail silently or cause render errors in browsers. Catching these before publishing takes thirty seconds; debugging them after the fact takes much longer.
Storing SVG source as plain text files in your posts/ directory alongside index.md is the correct version control strategy. Each diagram becomes a file like architecture-overview.svg committed to git. This means diffs show exactly what changed between iterations, you can roll back to any previous version of a diagram, and your diagrams are as portable and reproducible as the rest of your content.
Optimization for Hugo and Web Performance
AI tools - and design tools like Adobe Illustrator or Figma - often produce SVG with substantial bloat: vendor-specific metadata elements, redundant id attributes that reference nothing, empty <g> groups, unnecessary decimal precision in coordinates, and default attribute values that could be omitted. Before embedding any generated SVG in your Hugo blog, run it through SVGO.
SVGO (SVG Optimizer) is a Node.js command-line tool that applies a configurable set of optimization passes to an SVG file. Install it globally with npm install -g svgo, then run svgo diagram.svg -o diagram.min.svg. For most AI-generated SVG, this produces a 30% to 60% reduction in file size with no visible change to the rendered output. On a typical flowchart, that might mean going from 18 KB down to 8 KB - every kilobyte eliminated is a small LCP improvement multiplied across every visitor to every post that uses the diagram.
Hugo’s asset pipeline provides a second optimization layer that runs at build time. Rather than manually running SVGO before every commit, you can wire it into your Hugo shortcode. Using Hugo Pipes, a shortcode can load an SVG file from the post directory, minify it, and output it inline in the HTML:
{{ $svg := resources.Get .Params.src }}
{{ $minified := $svg | resources.Minify }}
{{ $minified.Content | safeHTML }}This approach ensures that every SVG on the site is always optimized, regardless of whether the author remembered to run SVGO manually. The build output is clean, minified inline SVG with no extra round-trips.
The inline vs. <img> embedding decision deserves careful thought. Inline SVG - pasting the raw SVG markup directly into the HTML - gives you full CSS control. Your dark mode variables work. You can animate elements with CSS. You can manipulate nodes with JavaScript. The tradeoff is that inline SVG inflates your HTML payload, is not cacheable separately from the page, and can create id collisions if the same SVG appears multiple times. The <img src="diagram.svg"> approach keeps your HTML clean, allows the browser to cache the SVG file independently, and avoids ID conflicts - but it creates a sandboxed context where the SVG cannot inherit CSS variables from the parent document. For dark mode theming, this matters: a CSS variable like var(--text-color) will not resolve inside an SVG loaded via <img>. The pragmatic rule: use inline SVG for any diagram that needs to participate in dark mode theming or CSS animation; use <img> for static diagrams that are self-contained.
Accessibility is non-negotiable. Any SVG used as a figure on your page must include a role="img" attribute on the root <svg> element, a <title> element containing a brief description, and optionally a <desc> element with a longer description for complex diagrams. This is the minimum requirement for WCAG 2.1 AA compliance. Screen readers will announce the title when they encounter the SVG, giving non-sighted users the same informational access as sighted ones.
Dark mode theming with CSS custom properties is what makes SVG genuinely superior to raster images for modern blogs. Define your theme colors as CSS variables in your stylesheet:
:root {
--diagram-stroke: #1a1a2e;
--diagram-fill: #f8f9fa;
--diagram-text: #1a1a2e;
--diagram-accent: #4361ee;
}
[data-theme="dark"] {
--diagram-stroke: #e2e8f0;
--diagram-fill: #1e293b;
--diagram-text: #e2e8f0;
--diagram-accent: #7c9fff;
}Then in your SVG, use these variables everywhere: stroke="var(--diagram-stroke)", fill="var(--diagram-fill)". When you prompt the LLM to generate the SVG, instruct it to use these variable names directly. The diagram becomes a first-class citizen of your theme system - light or dark, it always looks correct without any extra work.
Building a Repeatable SVG Workflow for Bloggers
Ad-hoc SVG generation gets tedious quickly. The goal is a repeatable four-step process that takes any diagram concept to a published, optimized graphic in under ten minutes. The steps are: (1) describe the diagram’s purpose and structure in plain English, clearly enumerating all nodes, edges, and labels; (2) generate Mermaid or SVG using the appropriate prompt template; (3) validate and refine in one to three iterations, targeting specific elements with surgical prompts; (4) optimize with SVGO and commit the SVG file to the posts/ directory alongside your Markdown.
The single highest-leverage thing you can do to accelerate this workflow is to build and maintain a library of prompt templates. Once you have crafted a prompt that reliably produces a clean, well-structured architecture diagram, save it in a local file. The same for sequence diagrams, comparison tables, and flowcharts. Over time, these templates encode your conventions - your preferred viewBox dimensions, your CSS variable names, your font choices - so you never start from scratch. Here are four production-ready templates:
Architecture Diagram Template:
Generate an SVG architecture diagram with viewBox="0 0 900 500". Use only <rect rx="6">,
<text>, <line>, and <g> elements. Use currentColor for strokes, var(--diagram-fill) for
box backgrounds, and var(--diagram-text) for all text. Group related services visually
using labeled <g> containers. The architecture is: [describe your services and their
connections, listing each component and each data flow direction].Sequence Diagram Template (Mermaid):
Generate a Mermaid sequence diagram for the following interaction flow. Include all
participant labels exactly as listed. Use activation boxes to show when each participant
is processing. Use dashed arrows for return/response messages. The flow is:
[enumerate each step: Actor -> Target: Action]Flowchart Template (Mermaid):
Generate a Mermaid flowchart (direction: TD) for the following decision process. Use
rectangular nodes for actions, diamond nodes for decisions, and rounded nodes for start/end.
Label every edge. The process is: [describe each step and decision branch explicitly].Comparison Table as SVG:
Generate an SVG comparison table with viewBox="0 0 800 400". Use a header row with
var(--diagram-accent) background. Alternate row colors using var(--diagram-fill) and a
slightly lighter variant. Use <text> elements aligned with explicit x/y coordinates.
The comparison covers: [list the columns and each row of data].For the Hugo/Nimbler workflow specifically, place SVG files directly in the post directory and reference them in Markdown as . Hugo will serve them as static assets. If you want inline SVG with CSS theming, use a shortcode instead:
{{< svg src="architecture.svg" alt="System architecture showing the three-tier deployment" >}}The shortcode reads the file, pipes it through Hugo’s minifier, and outputs inline HTML. This is the cleanest integration: the author works with named SVG files that are readable and diffable in git, and the build pipeline handles the rest.
Knowing when to fall back to a manual tool is as important as knowing when to use AI generation. Excalidraw is the right choice when you want a hand-drawn, informal aesthetic - whiteboard-style diagrams that signal “this is an exploratory concept, not a rigid specification.” Draw.io and diagrams.net are better for complex network topology diagrams with dozens of nodes and specific connector routing requirements; their auto-layout algorithms handle complexity that would take many AI iterations to get right. Figma is unmatched for polished product screenshots, UI mockups, and marketing-style visuals. AI SVG generation is fastest for the large middle ground: structured technical diagrams of moderate complexity where the logical structure can be described in prose. When the diagram is so complex that describing it in prose takes longer than drawing it, reach for a manual tool.
The practical test is this: can you fully describe every element of the diagram in a short paragraph? If yes, AI generation is almost certainly faster. If you find yourself writing a small essay just to specify the diagram’s structure, switch to a visual tool. The goal is always the fastest path to a clear, accurate, well-rendered diagram - and that path varies depending on the diagram.
The Long-Term Payoff
Building SVG generation into your blogging workflow is an investment that compounds. Every diagram you create as SVG is resolution-independent in perpetuity - no revisiting old posts to regenerate blurry images when display technology improves. Every diagram that uses CSS variables participates in your theme automatically - no manual updates when you redesign your site’s color palette. Every diagram stored as text is fully version-controlled, searchable, and portable.
The combination of a well-crafted prompt library, SVGO optimization, Hugo pipe integration, and CSS variable theming creates a workflow that is genuinely faster than exporting PNGs from a design tool for the majority of technical diagrams. It produces smaller files, better accessibility, stronger SEO signal, and effortless dark mode support. For technical bloggers who publish regularly, those advantages accumulate into a meaningfully better site and a meaningfully faster publishing cadence.
Start with Mermaid for your next sequence diagram or flowchart. Get comfortable with the generate-validate-refine loop. Build your first prompt template. Once the workflow feels natural, extend it to raw SVG for cases where Mermaid is not expressive enough. Within a few posts, the muscle memory will be there - and you will find it increasingly hard to justify ever exporting another PNG.