Skip to main content

Overview

Basic Memory can create visual representations of your knowledge graph using Obsidian canvas files. These visualizations help you:
  • See relationships between concepts
  • Understand knowledge structure
  • Present ideas visually
  • Plan projects and workflows
  • Document architectures

Canvas Format

Basic Memory uses the JSON Canvas 1.0 specification, an open format created by Obsidian. Canvas files (.canvas) are JSON files that define:
  • Nodes - Visual elements representing content
  • Edges - Connections between nodes
  • Layout - Positioning and styling

Creating a Canvas

Use the canvas tool to create visualizations:
canvas(
    nodes=[...],
    edges=[...],
    title="My Canvas",
    directory="diagrams"
)

Node Types

Canvas supports four node types:
Reference existing notes:
{
    "id": "node1",
    "type": "file",
    "file": "notes/authentication.md",
    "x": 0,
    "y": 0,
    "width": 400,
    "height": 300
}
Key points:
  • file must reference an existing file path
  • Path is relative to project root
  • Obsidian will show file preview

Edges

Edges connect nodes to show relationships:
{
    "id": "edge1",
    "fromNode": "node1",
    "toNode": "node2",
    "label": "implements"
}

Edge Properties

id
string
required
Unique identifier for the edge
fromNode
string
required
ID of the source node
toNode
string
required
ID of the target node
label
string
Optional label to describe the relationship
color
string
Color as hex code (e.g., "#FF0000") or preset ("1" through "6")

Styling

Node Colors

Style nodes with colors:
{
    "id": "node1",
    "type": "text",
    "text": "Important",
    "color": "1",  # Red
    "x": 0,
    "y": 0,
    "width": 200,
    "height": 100
}
Color presets:
  • "1" - Red
  • "2" - Orange
  • "3" - Yellow
  • "4" - Green
  • "5" - Cyan
  • "6" - Purple
Or use hex colors: "#FF5733"

Edge Colors

Style connections:
{
    "id": "edge1",
    "fromNode": "node1",
    "toNode": "node2",
    "color": "3",  # Yellow
    "label": "depends on"
}

Layout Strategies

Hierarchical Layout

Top-down or left-right hierarchy:
nodes = [
    # Top level
    {"id": "root", "x": 400, "y": 0, ...},
    
    # Second level
    {"id": "child1", "x": 100, "y": 200, ...},
    {"id": "child2", "x": 400, "y": 200, ...},
    {"id": "child3", "x": 700, "y": 200, ...},
    
    # Third level
    {"id": "leaf1", "x": 100, "y": 400, ...},
    {"id": "leaf2", "x": 400, "y": 400, ...},
]

Network Layout

Central hub with connections:
import math

# Center node
nodes = [{"id": "center", "x": 500, "y": 500, ...}]

# Surrounding nodes in circle
for i in range(6):
    angle = (2 * math.pi * i) / 6
    nodes.append({
        "id": f"node{i}",
        "x": 500 + 300 * math.cos(angle),
        "y": 500 + 300 * math.sin(angle),
        ...
    })

Grid Layout

Organized in rows and columns:
row_height = 250
col_width = 350

nodes = []
for row in range(3):
    for col in range(4):
        nodes.append({
            "id": f"node_{row}_{col}",
            "x": col * col_width,
            "y": row * row_height,
            "width": 300,
            "height": 200,
            ...
        })

Example Canvases

System Architecture

canvas(
    nodes=[
        # Frontend
        {
            "id": "frontend",
            "type": "file",
            "file": "docs/frontend-architecture.md",
            "x": 0,
            "y": 0,
            "width": 400,
            "height": 300,
            "color": "4"
        },
        # API
        {
            "id": "api",
            "type": "file",
            "file": "docs/api-design.md",
            "x": 450,
            "y": 0,
            "width": 400,
            "height": 300,
            "color": "5"
        },
        # Database
        {
            "id": "database",
            "type": "file",
            "file": "docs/database-schema.md",
            "x": 900,
            "y": 0,
            "width": 400,
            "height": 300,
            "color": "6"
        },
    ],
    edges=[
        {
            "id": "e1",
            "fromNode": "frontend",
            "toNode": "api",
            "label": "calls"
        },
        {
            "id": "e2",
            "fromNode": "api",
            "toNode": "database",
            "label": "queries"
        },
    ],
    title="System Architecture",
    directory="diagrams"
)

Project Roadmap

canvas(
    nodes=[
        # Phases
        {
            "id": "phase1",
            "type": "text",
            "text": "## Phase 1: Foundation\n- Setup\n- Basic features",
            "x": 0,
            "y": 0,
            "width": 300,
            "height": 200,
            "color": "4"
        },
        {
            "id": "phase2",
            "type": "text",
            "text": "## Phase 2: Enhancement\n- Advanced features\n- Optimization",
            "x": 350,
            "y": 0,
            "width": 300,
            "height": 200,
            "color": "3"
        },
        {
            "id": "phase3",
            "type": "text",
            "text": "## Phase 3: Launch\n- Testing\n- Deployment",
            "x": 700,
            "y": 0,
            "width": 300,
            "height": 200,
            "color": "1"
        },
    ],
    edges=[
        {"id": "e1", "fromNode": "phase1", "toNode": "phase2"},
        {"id": "e2", "fromNode": "phase2", "toNode": "phase3"},
    ],
    title="Project Roadmap",
    directory="planning"
)

Concept Map

canvas(
    nodes=[
        # Central concept
        {
            "id": "main",
            "type": "file",
            "file": "concepts/machine-learning.md",
            "x": 400,
            "y": 300,
            "width": 400,
            "height": 300,
            "color": "6"
        },
        # Related concepts
        {
            "id": "supervised",
            "type": "file",
            "file": "concepts/supervised-learning.md",
            "x": 0,
            "y": 0,
            "width": 350,
            "height": 250
        },
        {
            "id": "unsupervised",
            "type": "file",
            "file": "concepts/unsupervised-learning.md",
            "x": 850,
            "y": 0,
            "width": 350,
            "height": 250
        },
        {
            "id": "reinforcement",
            "type": "file",
            "file": "concepts/reinforcement-learning.md",
            "x": 425,
            "y": 650,
            "width": 350,
            "height": 250
        },
    ],
    edges=[
        {
            "id": "e1",
            "fromNode": "main",
            "toNode": "supervised",
            "label": "includes"
        },
        {
            "id": "e2",
            "fromNode": "main",
            "toNode": "unsupervised",
            "label": "includes"
        },
        {
            "id": "e3",
            "fromNode": "main",
            "toNode": "reinforcement",
            "label": "includes"
        },
    ],
    title="Machine Learning Concepts",
    directory="concepts"
)

Working with Claude

Ask Claude to create canvases naturally:

Architecture Visualization

You: Create a canvas showing our authentication system architecture.
Include the frontend, API gateway, auth service, and database.
Show the relationships between components.

Claude: [Creates canvas with file nodes for each component and edges
showing data flow]

Project Planning

You: Make a visual roadmap for Q1 with three phases: foundation,
enhancement, and launch. Show what depends on what.

Claude: [Creates canvas with text nodes for phases and edges showing
dependencies]

Concept Exploration

You: Create a concept map for semantic search showing how it relates
to embeddings, vector databases, and similarity search.

Claude: [Creates canvas linking related concept notes]

Viewing Canvases

Canvas files are stored in your project directory and can be opened in:

Obsidian

1

Open in Obsidian

Canvas files appear in the file explorer with a canvas icon
2

Interactive Editing

  • Drag nodes to reposition
  • Click edges to edit labels
  • Add new nodes and connections
  • Change colors and styling
3

Pan and Zoom

  • Scroll to zoom
  • Click and drag background to pan
  • Fit to screen with toolbar button

As JSON

Canvas files are plain JSON:
# View canvas file
cat diagrams/architecture.canvas | jq

# Edit with any text editor
code diagrams/architecture.canvas

Advanced Techniques

Dynamic Node IDs

Generate IDs programmatically:
import uuid

nodes = [
    {
        "id": str(uuid.uuid4()),
        "type": "text",
        "text": f"Node {i}",
        ...
    }
    for i in range(10)
]

Compute Layout Automatically

Calculate positions based on relationships:
def layout_tree(root, depth=0, offset_x=0):
    """Layout nodes in a tree structure"""
    nodes = [{
        "id": root["id"],
        "x": offset_x,
        "y": depth * 250,
        ...
    }]
    
    child_width = 400
    for i, child in enumerate(root.get("children", [])):
        child_offset = offset_x + i * child_width
        nodes.extend(layout_tree(child, depth + 1, child_offset))
    
    return nodes

Generate from Knowledge Graph

Create canvas from existing notes:
# Get related notes
context = build_context("memory://main-topic")

# Convert to canvas nodes
nodes = []
for i, result in enumerate(context["results"]):
    nodes.append({
        "id": result["permalink"],
        "type": "file",
        "file": f"{result['permalink']}.md",
        "x": (i % 3) * 400,
        "y": (i // 3) * 300,
        "width": 350,
        "height": 250
    })

# Create edges from relations
edges = []
for result in context["results"]:
    for relation in result.get("relations", []):
        edges.append({
            "id": f"{result['permalink']}-{relation['to']}",
            "fromNode": result["permalink"],
            "toNode": relation["to"],
            "label": relation["type"]
        })

Best Practices

Sketch your layout before asking Claude:
"Create a canvas with:
- Main concept at center
- 4 related concepts around it
- Use file nodes for existing notes
- Color code by category"
Maintain readable layouts:
# Good spacing
horizontal_gap = 50
vertical_gap = 50
node_width = 400
node_height = 300

x = col * (node_width + horizontal_gap)
y = row * (node_height + vertical_gap)
Use descriptive relationship labels:
# Good
{"label": "implements"}
{"label": "depends on"}
{"label": "extends"}

# Avoid
{"label": "related"}
{"label": "connected"}
Assign colors to indicate categories:
# Define color scheme
COLORS = {
    "frontend": "4",  # Green
    "backend": "5",   # Cyan
    "database": "6",  # Purple
    "external": "2",  # Orange
}

Troubleshooting

  1. Verify file has .canvas extension
  2. Check JSON is valid: cat file.canvas | jq
  3. Ensure file is in Obsidian vault directory
  1. Verify file path is correct and relative to project root
  2. Check file exists: ls notes/file.md
  3. Use exact path shown in Obsidian file explorer
  1. Increase spacing between nodes
  2. Check x,y coordinates are unique
  3. Consider different layout strategy
  1. Verify fromNode and toNode IDs exist
  2. Check IDs match exactly (case-sensitive)
  3. Ensure nodes have valid positions

Next Steps

Writing Notes

Create notes to reference in canvases

Building Context

Navigate your knowledge graph

JSON Canvas Spec

Full canvas specification

Canvas API

Complete API documentation

Build docs developers (and LLMs) love