archify

Create professional architecture diagrams as standalone HTML files with SVG graphics, a built-in dark/light theme toggle, and one-click export to PNG / JPEG / WebP / SVG. Use when the user asks for system architecture diagrams, infrastructure diagrams, cloud architecture visualizations, security diagrams, network topology diagrams, or any technical diagram showing system components and their relationships.

install
source · Clone the upstream repo
git clone https://github.com/tt-a1i/archify
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/tt-a1i/archify "$T" && mkdir -p ~/.claude/skills && cp -r "$T/archify" ~/.claude/skills/tt-a1i-archify-archify && rm -rf "$T"
manifest: archify/SKILL.md
source content

Archify Skill

Create professional technical architecture diagrams as self-contained HTML files with inline SVG, a theme toggle, and a built-in image/SVG export menu. No external runtime dependencies beyond Google Fonts.

Every diagram this skill produces ships with:

  • A Dark / Light theme toggle (top-right, persists in
    localStorage
    , respects
    prefers-color-scheme
    on first visit).
  • An Export menu with Copy PNG to clipboard plus downloads for PNG / JPEG / WebP (all rasterized natively at 4× source resolution for maximum sharpness) and SVG (vector, styles inlined). The SVG download is dual-theme self-contained: it ships with both dark and light variable sets plus a
    @media (prefers-color-scheme)
    rule, so embedding it in a GitHub README (or any
    <img>
    host that exposes a color scheme) makes it follow the reader's dark/light preference automatically. All rendering happens in-browser, no server.
  • A CSS-variable-driven color system so both themes remain visually consistent with the same SVG markup.

The Cardinal Rule: Use CSS Classes, Not Inline Colors

The theme toggle works by switching CSS custom properties. If you hardcode

fill="rgba(...)"
or
stroke="#22d3ee"
on SVG elements, those values will NOT update when the theme changes. Always prefer the class-based system.

Do this

<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-backend" stroke-width="1.5"/>
<text x="CX" y="CY" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">API Server</text>
<text x="CX" y="CY+16" class="t-muted" font-size="9" text-anchor="middle">FastAPI :8000</text>

Don't do this

<!-- Hardcoded colors break the theme toggle -->
<rect fill="rgba(6, 78, 59, 0.4)" stroke="#34d399" .../>
<text fill="white" .../>

Design System

Component color classes

Component TypeFill classText color classWhen to use
Frontend
c-frontend
t-frontend
Client apps, browsers, mobile, UI
Backend
c-backend
t-backend
Services, APIs, workers, daemons
Database
c-database
t-database
DBs, caches, log files, data stores
Cloud / AWS
c-cloud
t-cloud
Managed cloud services, infra
Security
c-security
t-security
Auth providers, secrets, guards
Message Bus
c-messagebus
t-messagebus
Kafka/RabbitMQ/SNS/Event buses
External/Generic
c-external
t-muted
Users, 3rd parties, anything uncategorized

Text on a dark or light background uses three neutral helpers:

Text classRole
t-primary
Component names / titles
t-muted
Sublabels, annotations
t-dim
Tertiary / footer metadata

Per-semantic text accents also exist:

t-frontend
,
t-backend
,
t-database
,
t-cloud
,
t-security
,
t-messagebus
,
t-external
— use when you want a label colored to match its component type (e.g., a small "OAI Protected" caption inside a cloud-type box).

Arrow classes

ClassMarker idSemantic
a-default
#arrowhead
Standard data/flow arrow
a-emphasis
#arrowhead-emphasis
Live event stream / hot path
a-security
#arrowhead-security
Auth / security flow (dashed)
a-dashed
#arrowhead-dashed
Async / secondary (dashed)

Always set

stroke-width
on the line (e.g.,
1.5
) — the class only sets color and dasharray.

Boundary classes

ClassPurpose
c-security-group
Dashed rose boundary for SGs
c-region
Large dashed amber region/cluster

Typography

Inherit from the SVG root (already wired to JetBrains Mono). Font sizes: 12px for component names, 9px for sublabels, 8px for annotations, 7px for tiny labels.

Visual Elements

Background grid: Automatically themed via

.c-grid
inside the
<pattern id="grid">
. Don't modify.

Component boxes: Rounded rectangles (

rx="6"
),
stroke-width="1.5"
, using the
.c-<type>
classes.

Arrow z-order: Draw connection arrows BEFORE component boxes (earlier in the SVG). SVG paints in document order, so arrows drawn first appear behind shapes drawn later.

Masking arrows behind transparent fills: Component fills are semi-transparent, which means arrows behind them bleed through. The template solves this with a two-rect pattern — an opaque mask rect, then the styled component on top:

<!-- 1. opaque mask (themed: dark=#0f172a, light=#ffffff) -->
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
<!-- 2. styled component on top -->
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-database" stroke-width="1.5"/>

Always use

c-mask
instead of hardcoded
fill="#0f172a"
— the mask color itself is themed.

Message buses / Event buses: Small connector elements between services:

<rect x="X" y="Y" width="120" height="20" rx="4" class="c-messagebus" stroke-width="1"/>
<text x="CENTER_X" y="Y+14" class="t-messagebus" font-size="7" text-anchor="middle">Kafka / RabbitMQ</text>

Spacing Rules

CRITICAL: When stacking components vertically, ensure proper spacing to avoid overlaps:

  • Standard component height: 60px for services, 80-120px for larger components
  • Minimum vertical gap between components: 40px
  • Inline connectors (message buses): Place IN the gap between components, not overlapping

Example vertical layout:

Component A: y=70,  height=60  -> ends at y=130
Gap:         y=130 to y=170   -> 40px gap, place bus at y=140 (20px tall)
Component B: y=170, height=60  -> ends at y=230

Wrong: Placing a message bus at y=160 when Component B starts at y=170 (causes overlap) Right: Placing a message bus at y=140, centered in the 40px gap (y=130 to y=170)

Security Group & Region Boundary Padding

When a component sits inside a

c-security-group
or
c-region
boundary, the small label on the boundary (e.g.,
sg-name :port
,
AWS Region: us-west-2
) needs room above the inner component — otherwise the label visually crashes into the box below it.

Rule: boundary

y
= inner-component
y
− 30, boundary
height
= inner-component
height
+ 50. Place the label 18px below the boundary top (baseline). This yields ~12px clear gap between the label baseline and the inner component's top edge.

Example — a Load Balancer (y=280, h=50) inside a security group:

<!-- Security group — extends 30px above and 20px below the inner box -->
<rect x="350" y="250" width="120" height="100" rx="8" class="c-security-group" stroke-width="1"/>
<text x="358" y="268" class="t-security" font-size="8">sg-name :port</text>

<!-- Inner component — unchanged coordinates -->
<rect x="360" y="280" width="100" height="50" rx="6" class="c-mask"/>
<rect x="360" y="280" width="100" height="50" rx="6" class="c-cloud" stroke-width="1.5"/>

If the inner component is taller (e.g., a 100px multi-line box), keep the 30/50 offsets — the extra vertical room on top stays the same, the bottom padding grows naturally.

Legend Placement

CRITICAL: Place legends OUTSIDE all boundary boxes (region boundaries, cluster boundaries, security groups).

  • Calculate where all boundaries end (y position + height)
  • Place legend at least 20px below the lowest boundary
  • Expand SVG viewBox height if needed to accommodate

Layout Structure

  1. Header — Title with pulsing dot indicator, subtitle
  2. Toolbar (auto-included from template) — theme toggle + export menu, top-right fixed position
  3. Main SVG diagram — contained in rounded border card
  4. Summary cards — grid of 3 cards below diagram with key details
  5. Footer — minimal metadata line

Component Box Pattern

<rect x="X" y="Y" width="W" height="H" rx="6" class="c-mask"/>
<rect x="X" y="Y" width="W" height="H" rx="6" class="c-<type>" stroke-width="1.5"/>
<text x="CENTER_X" y="Y+20" class="t-primary" font-size="11" font-weight="600" text-anchor="middle">LABEL</text>
<text x="CENTER_X" y="Y+36" class="t-muted" font-size="9" text-anchor="middle">sublabel</text>

Arrow Patterns

<!-- Standard -->
<line x1="..." y1="..." x2="..." y2="..." class="a-default" stroke-width="1.5" marker-end="url(#arrowhead)"/>

<!-- Emphasis (live events / hot path) -->
<line x1="..." y1="..." x2="..." y2="..." class="a-emphasis" stroke-width="1.5" marker-end="url(#arrowhead-emphasis)"/>

<!-- Security / auth flow (dashed) -->
<path d="..." class="a-security" stroke-width="1.5" marker-end="url(#arrowhead-security)"/>

<!-- Async / secondary (dashed) -->
<path d="..." class="a-dashed" stroke-width="1" marker-end="url(#arrowhead-dashed)"/>

Pair each arrow class with the matching marker id (same suffix).

Info Card Pattern

<div class="card">
  <div class="card-header">
    <div class="card-dot COLOR"></div>
    <h3>Title</h3>
  </div>
  <ul>
    <li>&bull; Item one</li>
    <li>&bull; Item two</li>
  </ul>
</div>

Valid

card-dot
colors:
cyan
,
emerald
,
violet
,
amber
,
rose
,
orange
,
slate
— all automatically re-theme. Pair the dot to its component semantic (e.g.,
orange
for a "Messaging" card,
slate
for an "External Services" card).

Template

Copy and customize the template at

assets/template.html
. Customization points:

  1. Update the
    <title>
    and header
    <h1>
    text + subtitle
  2. Modify SVG
    viewBox
    dimensions if needed (default:
    1000 x 680
    )
  3. Add/remove/reposition component boxes using the
    .c-<type>
    classes
  4. Draw connection arrows using
    .a-<variant>
    classes
  5. Update the three summary cards
  6. Update footer metadata

Do NOT remove the

.toolbar
element, the
<script>
blocks, or the
:root
/
[data-theme="..."]
CSS. Those are what give every generated diagram the theme toggle and export buttons.

Output

Produce a single self-contained

.html
file with:

  • Embedded CSS (no external stylesheets except Google Fonts)
  • Inline SVG (no external images)
  • Small amount of embedded JS (theme toggle + export) — keep as-is from template

The file should render correctly when opened directly in any modern browser. The Export menu should cleanly copy PNG to the clipboard, download PNG / JPEG / WebP (all at 4× source resolution, rendered natively by the browser — no bitmap upsampling), and download a dual-theme self-contained SVG whose colors follow the embedding host's

prefers-color-scheme
(dark by default; swaps to light under a light host;
svg[data-theme="..."]
still works as a manual override).