How to Generate SVG and HTML Artifacts from Claude Skills

Claude skills generate artifacts by returning a JSON payload containing a base64-encoded content_base64 string, a declared mime_type such as image/svg+xml or text/html, and a filename, which the Claude runtime materializes as a downloadable or inline-previewable file.

The anthropics/claude-plugins-community repository demonstrates how Claude skills can produce rich media outputs beyond plain text. By implementing the artifact return pattern, developers can generate self-contained SVG diagrams, HTML pages, and other file types directly from skill executions, enabling visual communication within Claude Code workflows.

The Artifact Return Pattern in Claude Plugins

When a skill generates an artifact, it serializes the output into a specific JSON structure. According to the source code patterns found in eli5/skills/eli5/SKILL.md and related plugin configurations, the skill must return an object with an artifact key containing three critical fields: filename, mime_type, and content_base64.

The content_base64 field holds the base64-encoded bytes of the file, allowing binary and text-based formats to transmit reliably through the JSON API. The Claude runtime intercepts this payload, decodes the content, and presents it to the user as a file attachment or inline preview.

Generating SVG Artifacts from Skills

The QuickDesign plugin provides a concrete example of SVG artifact generation, shipping with quickdesign/.claude-plugin/icon.svg as a static asset. Dynamic generation follows the same pattern: construct the SVG markup, encode it to base64, and wrap it in the artifact JSON structure with mime_type set to image/svg+xml.

import json
import base64

def generate_flowchart_svg():
    # Construct SVG markup

    svg_content = """<svg xmlns="http://www.w3.org/2000/svg" width="200" height="100">
      <rect x="10" y="10" width="180" height="80" fill="#f0f0f0" stroke="#333"/>
      <text x="100" y="55" font-size="14" text-anchor="middle">Process Flow</text>
    </svg>"""
    
    # Encode to base64

    encoded = base64.b64encode(svg_content.encode('utf-8')).decode('utf-8')
    
    # Return artifact payload

    return json.dumps({
        "artifact": {
            "filename": "flowchart.svg",
            "mime_type": "image/svg+xml",
            "content_base64": encoded
        }
    })

print(generate_flowchart_svg())

When this payload reaches the Claude runtime, users receive flowchart.svg as a downloadable vector graphic.

Creating HTML Artifacts for Rich Content

The eli5 skill explicitly demonstrates HTML artifact generation, prompting Claude to return explanations as self-contained HTML documents with embedded images. This approach uses mime_type: "text/html" and serializes the complete HTML document into the content_base64 field.

import json
import base64

def create_explanation_html(title, image_url, explanation_text):
    html_doc = f"""<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{title}</title>
    <style>
        body {{ font-family: system-ui, sans-serif; max-width: 800px; margin: 2rem auto; }}
        img {{ max-width: 100%; height: auto; border-radius: 8px; }}
    </style>
</head>
<body>
    <h1>{title}</h1>
    <img src="{image_url}" alt="{title}">
    <p>{explanation_text}</p>
</body>
</html>"""
    
    encoded = base64.b64encode(html_doc.encode('utf-8')).decode('utf-8')
    
    return json.dumps({
        "artifact": {
            "filename": f"{title.lower().replace(' ', '-')}.html",
            "mime_type": "text/html",
            "content_base64": encoded
        }
    })

# Example usage

html_payload = create_explanation_html(
    "Quantum Entanglement",
    "https://example.com/entanglement.png",
    "Quantum entanglement is a physical phenomenon where particles become correlated..."
)
print(html_payload)

This pattern produces standalone HTML files that render correctly in any browser, preserving styling and external resource references.

Consuming Artifacts in Downstream Skills

Artifacts generated by one skill can serve as inputs for subsequent skills in multi-step workflows. The Claude runtime makes artifact file paths available to downstream processes, allowing skills to read, modify, or embed previous outputs.

import json

def embed_svg_in_report(artifact_path):
    """Read a previously generated SVG artifact and embed it in markdown."""
    # Read the artifact file provided by the runtime

    with open(artifact_path, "r") as f:
        svg_content = f.read()
    
    # Create markdown with embedded SVG

    markdown_output = f"""## Generated Diagram

{svg_content}

*Figure 1: Visualization generated by upstream skill*
"""
    
    return json.dumps({
        "content": markdown_output
    })

# The artifact_path is provided by Claude's runtime context

Summary

  • Claude skills generate artifacts by returning a JSON object with an artifact key containing filename, mime_type, and content_base64.
  • SVG artifacts use image/svg+xml MIME type and work for diagrams, icons, and vector graphics, as demonstrated in quickdesign/.claude-plugin/icon.svg.
  • HTML artifacts use text/html MIME type to deliver rich, styled documents with embedded media, following the pattern in eli5/skills/eli5/SKILL.md.
  • All artifact content must be base64-encoded to ensure safe JSON transport of binary and text data.
  • Downstream skills can consume artifacts by reading their file paths provided by the Claude runtime, enabling complex multi-step workflows.

Frequently Asked Questions

What MIME types are supported for Claude skill artifacts?

The anthropics/claude-plugins-community repository primarily demonstrates image/svg+xml for vector graphics and text/html for web documents. The plugin configuration in .claude-plugin/marketplace.json suggests the architecture supports standard web formats, and the base64 encoding mechanism theoretically allows any file type, though implementations should validate against Claude's runtime whitelist.

How do I reference an artifact in a subsequent skill?

The Claude runtime makes artifact file paths available to downstream skills through the execution context. Skills receive the path as a parameter or environment reference, allowing them to open the file directly using standard file I/O operations, as shown in consumption patterns where open(artifact_path, "r") reads previously generated SVG content.

Can skills generate binary artifacts like PNG or PDF?

Yes, the base64 encoding requirement in the content_base64 field supports binary formats. While the repository examples focus on text-based SVG and HTML, encoding binary bytes to base64 and setting the appropriate MIME type (such as image/png or application/pdf) follows the same JSON payload structure and will materialize correctly in the Claude interface.

Where are artifacts stored when returned from a skill?

Artifacts materialize within the Claude execution environment's file system, typically in paths accessible to the current session or downstream skills. The runtime handles temporary storage and cleanup, presenting the file to the user as a download link or inline preview while making the filesystem path available to subsequent skill invocations in the same conversation thread.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →