Magam
Overview
Magam is a React-based library for creating visual diagrams through code. It enables AI-first diagram creation where users describe their intent in natural language, and the AI generates React/TSX code that renders as visual diagrams. The philosophy is "describing" rather than "drawing" - transforming thoughts into structured visual representations.
When to Use This Skill
- •Creating mind maps to organize ideas or knowledge
- •Building system architecture diagrams
- •Visualizing flowcharts and processes
- •Creating overview/brainstorming diagrams with sticky notes
- •Generating visual documentation from text descriptions
- •Any task requiring code-based diagram generation
Editing Nodes with Copy Node ID
Magam supports a node ID copy feature that enables targeted editing of specific nodes. Users can select a node in the canvas and copy its fully-qualified ID, then paste it into a prompt for the AI to locate and edit.
How It Works
- •Select a node by clicking it on the canvas
- •Copy with
Cmd+C(Mac) /Ctrl+C(Windows/Linux) - •The fully-qualified node ID is copied to clipboard (e.g.,
mindmap.mindmap-0.ai-table-demo) - •Paste the ID into a prompt to tell the AI which node to edit
Node ID Format
Node IDs follow the pattern: {mindmapId}.{nodeId}
- •If the MindMap has an explicit
idprop (e.g.,<MindMap id="main">), the prefix is that ID (e.g.,main.intro) - •If no explicit
id, an auto-generated ID likemindmap-0is used (e.g.,mindmap-0.root) - •Top-level canvas elements (Shape, Sticky, Text) outside a MindMap use their own
iddirectly
AI Workflow for Targeted Edits
When a user provides a copied node ID, the AI should:
- •Find the node in the TSX source by matching the
idprop value (the last segment of the path) - •Identify the MindMap it belongs to by matching the MindMap
idprop (the first segment) - •Edit the node's content as requested
Example prompt from user:
"Add a row for 'Alice' to the table in
mindmap.mindmap-0.ai-table-demo"
AI interpretation:
- •MindMap: auto-generated
mindmap-0(the first/default MindMap in the file) - •Node:
ai-table-demo - •Action: Find
<Node id="ai-table-demo">and add a table row
Multi-Select
Multiple nodes can be selected and copied at once. Each ID is separated by a newline in the clipboard. The AI should handle each node independently when editing.
Core Components
All components are imported from @magam/core:
import { Canvas, Shape, Sticky, MindMap, Node, Edge, Text, Markdown } from '@magam/core';
Canvas (Required Root)
Every Magam diagram must be wrapped in a Canvas component.
<Canvas>
{/* All diagram elements go here */}
</Canvas>
Shape
Rectangle/box element for architecture diagrams and flowcharts.
Props:
- •
id(required): Unique identifier - •
x,y: Absolute position coordinates - •
width,height: Size in pixels - •
label: Text label (alternative to children) - •
className: Tailwind CSS classes for styling - •
anchor: ID of another Shape for relative positioning - •
position: Position relative to anchor ("right", "bottom", "left", "top") - •
gap: Distance from anchor element
Usage Patterns:
{/* Absolute positioning */}
<Shape id="box1" x={100} y={100}>Content</Shape>
{/* With size */}
<Shape id="box2" x={200} y={100} width={180} height={80}>Sized Box</Shape>
{/* Relative positioning with anchor */}
<Shape id="api" anchor="users" position="right" gap={120}>
<Text>API Server</Text>
<Edge to="users" />
</Shape>
{/* With Tailwind styling */}
<Shape id="success" className="bg-green-50 border-green-300 text-green-700">
Success State
</Shape>
Sticky
Sticky note element, similar to Shape but styled as a sticky note.
<Sticky id="idea" x={100} y={100}>
My Idea
<Edge to="target" />
</Sticky>
{/* With glass effect */}
<Sticky id="glass" className="bg-white/50 backdrop-blur-sm border-white/30">
Glass Effect
</Sticky>
MindMap
Container for hierarchical mind map structures.
Props:
- •
id: MindMap identifier (required for multiple MindMaps) - •
x,y: Position on canvas (default: 0, 0) - •
layout: "tree" (horizontal), "bidirectional" (left+right), or "radial" (circular) - •
spacing: Gap between nodes
<MindMap id="main" layout="tree" spacing={80}>
<Node id="root">Root Topic</Node>
<Node id="child1" from="root">Child 1</Node>
<Node id="child2" from="root">Child 2</Node>
<Node id="grandchild" from="child1">Grandchild</Node>
</MindMap>
Node
MindMap node element. Must be used inside a MindMap.
Props:
- •
id(required): Unique identifier - •
from: Parent node ID (creates connection automatically) - •
bubble: Enable floating label when zoomed out (semantic zoom)
Content Options:
- •Plain text:
<Node id="x">Plain text</Node> - •Text component:
<Node id="x"><Text>Styled</Text></Node> - •Multiple Text:
<Node id="x"><Text>Line 1</Text><Text>Line 2</Text></Node> - •Markdown:
<Node id="x"><Markdown>content</Markdown></Node> - •Markdown with bubble:
<Node id="x"><Markdown bubble>{content}</Markdown></Node>
Semantic Zoom (Bubble)
When zoomed out (zoom < 0.4), nodes with the bubble prop display a floating label overlay. The label text is auto-extracted from the first line of content.
Usage:
{/* On Node directly */}
<Node id="x" bubble>
<Text>This text becomes bubble label</Text>
</Node>
{/* On Markdown inside Node */}
<Node id="x">
<Markdown bubble>{`
# Heading becomes bubble
Content here...
`}</Markdown>
</Node>
{/* On Shape */}
<Shape id="x" label="Bubble text" bubble>
<Text>Shape content</Text>
</Shape>
Behavior:
- •First line of content is extracted as bubble text
- •Markdown syntax (headings, bold, etc.) is cleaned
- •Text over 40 characters is truncated with
... - •Bubble appears as floating overlay on top of original content
Best Practices:
| Level | Recommendation | Reason |
|---|---|---|
| Root node | Always use | Main topic visibility at any zoom |
| Level 1-2 (children of root) | Recommended | Section titles remain readable when zoomed out |
| Level 3 | Selective | Only for key concepts that need visibility |
| Level 4+ | Usually skip | Too many bubbles cause visual clutter |
- •Use for navigation nodes: Nodes with Table of Contents or section headers benefit from bubbles
- •Use for key landmarks: Important concepts users need to locate quickly
- •Skip for leaf nodes: Detail nodes don't need bubble labels—users will zoom in to read them
- •Skip for repetitive content: If many siblings have similar structure, bubble only the parent
{/* Good: bubbles on structural nodes */}
<MindMap id="docs">
<Node id="root" bubble>Main Topic</Node>
<Node id="section1" from="root" bubble>Section 1</Node>
<Node id="section2" from="root" bubble>Section 2</Node>
<Node id="detail1" from="section1">Detail (no bubble)</Node>
</MindMap>
Text
Standalone or inline text element.
Props:
- •
id: Identifier (for standalone) - •
x,y: Position (for standalone) - •
className: Tailwind CSS classes
{/* Standalone text on canvas */}
<Text id="title" x={200} y={30}>Page Title</Text>
{/* Styled text */}
<Text className="text-xl font-bold text-blue-600">Styled Text</Text>
{/* Inside Shape */}
<Shape id="box">
<Text className="font-bold">Title</Text>
<Text className="text-sm text-gray-500">Subtitle</Text>
</Shape>
Markdown
Rich text content with Markdown support. Typically used inside Node.
Supported Features:
- •Headers:
# H1,## H2,### H3 - •Emphasis:
**bold**,*italic* - •Lists:
- itemor1. item - •Code:
`inline`and code blocks with ``` - •Tables:
| col1 | col2 | - •Blockquotes:
> quote
<Node id="docs">
<Markdown>{`
### API Reference
| Method | Endpoint |
|--------|----------|
| GET | /users |
| POST | /users |
\`\`\`typescript
function hello() {
return "world";
}
\`\`\`
`}</Markdown>
</Node>
Node Links (Internal Navigation)
Navigate between nodes using the node: scheme in Markdown links. Clicking a node link smoothly animates the viewport to the target node.
Syntax: [link text](node:/mindmapId/nodeId)
<Node id="intro">
<Markdown>{`
## Introduction
Learn the basics first, then move on.
[Next: Core Concepts](node:/main/concepts)
`}</Markdown>
</Node>
<Node id="concepts" from="intro">
<Markdown>{`
## Core Concepts
- Canvas: Infinite drawing area
- MindMap: Auto-layout container
- Node: Content container
[← Previous](node:/main/intro) | [Next →](node:/main/examples)
`}</Markdown>
</Node>
Path Formats:
- •
/mindmapId/nodeId→ navigates tomindmapId.nodeId - •
/nodeId→ navigates tonodeId(for single MindMap)
Styling: Node links are styled with indigo color and arrow prefix (→) to distinguish from external links.
Edge
Connection line between elements.
Props:
- •
from: Source element ID - •
to: Target element ID
{/* Standalone edge */}
<Edge from="box1" to="box2" />
{/* Inside Shape (only 'to' needed) */}
<Shape id="api">
<Text>API</Text>
<Edge to="database" />
</Shape>
Styling with Tailwind CSS
All components support className prop for Tailwind CSS styling.
Colors and States
<Shape className="bg-green-50 border-green-300 text-green-700">Success</Shape> <Shape className="bg-yellow-50 border-yellow-300 text-yellow-700">Warning</Shape> <Shape className="bg-red-50 border-red-300 text-red-700">Error</Shape>
Effects
<Shape className="bg-gradient-to-r from-blue-400 to-purple-500 text-white border-none"> Gradient </Shape> <Shape className="shadow-xl">Shadow</Shape> <Sticky className="bg-white/50 backdrop-blur-sm">Glass Effect</Sticky>
Borders
<Shape className="rounded-2xl">Rounded</Shape> <Shape className="border-dashed border-2">Dashed</Shape> <Shape className="border-4 border-indigo-500">Thick Border</Shape>
Sizing
<Shape width={180} height={80}>Props sizing</Shape>
<Shape className="w-[200px] h-[60px]">Tailwind sizing</Shape>
Common Patterns
Architecture Diagram
<Canvas>
<Text id="title" x={200} y={30}>System Architecture</Text>
<Shape id="users" x={50} y={100}>
<Text>Users</Text>
</Shape>
<Shape id="api" anchor="users" position="right" gap={120}>
<Text>API Server</Text>
<Edge to="users" />
</Shape>
<Shape id="db" anchor="api" position="right" gap={120}>
<Text>Database</Text>
<Edge to="api" />
</Shape>
<Shape id="auth" anchor="api" position="bottom" gap={80}>
<Text>Auth Service</Text>
<Edge to="api" />
</Shape>
</Canvas>
Knowledge Mind Map
<Canvas>
<MindMap id="knowledge" layout="tree" spacing={80}>
<Node id="root">
<Markdown>{`# Main Topic`}</Markdown>
</Node>
<Node id="category1" from="root">Category 1</Node>
<Node id="item1a" from="category1">Item 1A</Node>
<Node id="item1b" from="category1">Item 1B</Node>
<Node id="category2" from="root">Category 2</Node>
<Node id="item2a" from="category2">
<Markdown>{`
**Detailed Item**
- Point 1
- Point 2
`}</Markdown>
</Node>
</MindMap>
</Canvas>
Multiple MindMaps
Place multiple independent MindMaps on a single Canvas. Each MindMap has its own ID namespace, so node IDs won't conflict.
Key Features:
- •Scoped IDs: Same node ID can exist in different MindMaps
- •Positioning: Use
x,yprops to position each MindMap - •Cross-MindMap Edges: Use dot notation
mapId.nodeIdfor references
<Canvas>
{/* First MindMap */}
<MindMap id="concepts" layout="bidirectional">
<Node id="root">
<Markdown>{`# Core Concepts`}</Markdown>
</Node>
<Node id="feature1" from="root">Feature A</Node>
<Node id="feature2" from="root">Feature B</Node>
</MindMap>
{/* Second MindMap - positioned to the right */}
<MindMap id="details" layout="tree" x={600} y={0}>
<Node id="root">
<Markdown>{`## Details`}</Markdown>
</Node>
<Node id="item1" from="root">Detail 1</Node>
<Node id="item2" from="root">Detail 2</Node>
</MindMap>
{/* Cross-MindMap connection using dot notation */}
<Edge from="concepts.feature1" to="details.item1" />
</Canvas>
Brainstorming with Stickies
<Canvas>
<Text id="title" x={200} y={30}>Brainstorm</Text>
<Sticky id="idea1" x={100} y={100}>
Core Idea
<Edge to="central" />
</Sticky>
<Sticky id="idea2" x={100} y={200}>
Supporting Idea
<Edge to="central" />
</Sticky>
<Shape id="central" x={300} y={150}>Central Concept</Shape>
</Canvas>
Best Practices
- •Always use unique IDs for all elements with id prop
- •Use semantic IDs that describe the element's purpose
- •Prefer relative positioning with
anchor/position/gapfor maintainable layouts - •Use Markdown for rich content in mind map nodes
- •Do not add emojis unless the user explicitly requests them
- •Group related content using comments in JSX
- •Use consistent styling with Tailwind utility classes
- •Keep node content concise - use child nodes for detailed breakdowns
- •Split large MindMaps into multiple smaller ones - Rather than cramming everything into one huge MindMap, separate by topic or section. This makes hierarchies clearer and improves readability. Use
anchorpositioning to arrange them spatially. - •Use
bubblefor semantic zoom - Addbubbleprop to root nodes and level 1-2 children so section titles remain visible when zoomed out. Skip bubbles on level 4+ detail nodes to avoid visual clutter.
File Structure
Magam files are TypeScript/TSX files that export a React component:
import { Canvas, MindMap, Node, Text, Markdown } from '@magam/core';
export default function MyDiagram() {
return (
<Canvas>
{/* Diagram content */}
</Canvas>
);
}
Files are typically placed in an examples/ directory with descriptive names like architecture.tsx, mindmap.tsx, overview.tsx.