> ## Documentation Index
> Fetch the complete documentation index at: https://supermemory-capy-add-llmstxt-summary-and.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Memory Graph

> Interactive visualization for documents, memories and connections

Memory Graph is a React component that visualizes your Supermemory documents and memories as an interactive network. Documents appear as rectangular nodes, memories as hexagonal nodes, and connections between them show relationships and similarity.

<Card title="@supermemory/memory-graph on npm" icon="https://mintcdn.com/supermemory-capy-add-llmstxt-summary-and/LIMkcglt81IfjBVR/icons/hugeicons/package.svg?fit=max&auto=format&n=LIMkcglt81IfjBVR&q=85&s=e4fde81dc315fb6f6f50b11f4d2f8220" href="https://www.npmjs.com/package/@supermemory/memory-graph" width="24" height="24" data-path="icons/hugeicons/package.svg">
  Check out the NPM page for more details
</Card>

## Installation

```bash theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
npm install @supermemory/memory-graph
```

**Requirements:** React 18.0.0 or higher

## Quick start

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
'use client'; // For Next.js App Router

import { MemoryGraph } from '@supermemory/memory-graph';
import type { DocumentWithMemories } from '@supermemory/memory-graph';
import { useEffect, useState } from 'react';

export default function GraphPage() {
  const [documents, setDocuments] = useState<DocumentWithMemories[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<Error | null>(null);

  useEffect(() => {
    fetch('/api/graph')
      .then(res => res.json())
      .then(data => {
        setDocuments(data.documents);
        setIsLoading(false);
      })
      .catch(err => {
        setError(err);
        setIsLoading(false);
      });
  }, []);

  return (
    <div style={{ height: '100vh' }}>
      <MemoryGraph
        documents={documents}
        isLoading={isLoading}
        error={error}
        variant="console"
      />
    </div>
  );
}
```

## Backend API route

Create an API route to fetch documents from Supermemory:

<CodeGroup>
  ```typescript Next.js App Router theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  // app/api/graph/route.ts
  import { NextResponse } from 'next/server';

  export async function GET() {
    const response = await fetch('https://api.supermemory.ai/v3/documents/documents', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
      },
      body: JSON.stringify({
        page: 1,
        limit: 500,
        sort: 'createdAt',
        order: 'desc',
      }),
    });

    const data = await response.json();
    return NextResponse.json(data);
  }
  ```

  ```typescript Next.js Pages Router theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  // pages/api/graph.ts
  import type { NextApiRequest, NextApiResponse } from 'next';

  export default async function handler(req: NextApiRequest, res: NextApiResponse) {
    const response = await fetch('https://api.supermemory.ai/v3/documents/documents', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
      },
      body: JSON.stringify({ page: 1, limit: 500, sort: 'createdAt', order: 'desc' }),
    });

    const data = await response.json();
    res.json(data);
  }
  ```

  ```javascript Express theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  app.get('/api/graph', async (req, res) => {
    const response = await fetch('https://api.supermemory.ai/v3/documents/documents', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${process.env.SUPERMEMORY_API_KEY}`,
      },
      body: JSON.stringify({ page: 1, limit: 500, sort: 'createdAt', order: 'desc' }),
    });

    const data = await response.json();
    res.json(data);
  });
  ```
</CodeGroup>

<Warning>
  Never expose your Supermemory API key to the client. Always fetch data through your backend.
</Warning>

***

## Variants

**Console Variant** - Full-featured dashboard view (0.8x zoom, space selector visible):

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<MemoryGraph documents={documents} variant="console" />
```

**Consumer Variant** - Embedded widget view (0.5x zoom, space selector hidden):

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<MemoryGraph documents={documents} variant="consumer" />
```

***

## Examples

### With pagination

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
'use client';

import { MemoryGraph } from '@supermemory/memory-graph';
import { useCallback, useEffect, useState } from 'react';

export default function PaginatedGraph() {
  const [documents, setDocuments] = useState([]);
  const [page, setPage] = useState(1);
  const [hasMore, setHasMore] = useState(true);
  const [isLoading, setIsLoading] = useState(true);
  const [isLoadingMore, setIsLoadingMore] = useState(false);

  useEffect(() => { fetchPage(1, false); }, []);

  const fetchPage = async (pageNum, append) => {
    pageNum === 1 ? setIsLoading(true) : setIsLoadingMore(true);

    const res = await fetch(`/api/graph?page=${pageNum}&limit=100`);
    const data = await res.json();

    append ? setDocuments(prev => [...prev, ...data.documents]) : setDocuments(data.documents);
    setHasMore(data.pagination.currentPage < data.pagination.totalPages);
    setIsLoading(false);
    setIsLoadingMore(false);
  };

  const loadMore = useCallback(async () => {
    if (!isLoadingMore && hasMore) {
      const nextPage = page + 1;
      setPage(nextPage);
      await fetchPage(nextPage, true);
    }
  }, [page, hasMore, isLoadingMore]);

  return (
    <MemoryGraph
      documents={documents}
      isLoading={isLoading}
      isLoadingMore={isLoadingMore}
      hasMore={hasMore}
      totalLoaded={documents.length}
      loadMoreDocuments={loadMore}
    />
  );
}
```

### Highlighting search results

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<MemoryGraph
  documents={documents}
  highlightDocumentIds={searchResults}
  highlightsVisible={searchResults.length > 0}
/>
```

### Controlled space selection

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<MemoryGraph
  documents={documents}
  selectedSpace={selectedSpace}
  onSpaceChange={setSelectedSpace}
  showSpacesSelector={false}
/>
```

### Custom empty state

```tsx theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
<MemoryGraph documents={documents} isLoading={isLoading}>
  <div style={{ textAlign: 'center', padding: '2rem' }}>
    <h2>No memories yet</h2>
    <p>Add content to see your knowledge graph</p>
  </div>
</MemoryGraph>
```

***

## Props reference

### Core props

| Prop | Type | Default | Description |
| - | - | - | - |
| `documents` | `DocumentWithMemories[]` | required | Array of documents to display |
| `isLoading` | `boolean` | `false` | Shows loading indicator |
| `error` | `Error \| null` | `null` | Error to display |
| `variant` | `"console" \| "consumer"` | `"console"` | Visual variant |
| `children` | `ReactNode` | - | Custom empty state content |

### Pagination props

| Prop | Type | Default | Description |
| - | - | - | - |
| `isLoadingMore` | `boolean` | `false` | Shows indicator when loading more |
| `hasMore` | `boolean` | `false` | Whether more documents available |
| `totalLoaded` | `number` | - | Total documents currently loaded |
| `loadMoreDocuments` | `() => Promise<void>` | - | Callback to load more |
| `autoLoadOnViewport` | `boolean` | `true` | Auto-load when 80% visible |

### Display props

| Prop | Type | Default | Description |
| - | - | - | - |
| `showSpacesSelector` | `boolean` | variant-based | Show space filter dropdown |
| `highlightDocumentIds` | `string[]` | `[]` | Document IDs to highlight |
| `highlightsVisible` | `boolean` | `true` | Whether highlights shown |
| `occludedRightPx` | `number` | `0` | Pixels occluded on right |

### Controlled state props

| Prop | Type | Description |
| - | - | - |
| `selectedSpace` | `string` | Currently selected space (use `"all"` for all) |
| `onSpaceChange` | `(spaceId: string) => void` | Callback when space changes |
| `memoryLimit` | `number` | Max memories per document when space selected |

***

## Data types

### DocumentWithMemories

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
interface DocumentWithMemories {
  id: string;
  customId?: string | null;
  title?: string | null;
  content?: string | null;
  summary?: string | null;
  url?: string | null;
  source?: string | null;
  type?: string | null;
  status: 'pending' | 'processing' | 'done' | 'failed';
  metadata?: Record<string, string | number | boolean> | null;
  createdAt: string | Date;
  updatedAt: string | Date;
  memoryEntries: MemoryEntry[];
}
```

### MemoryEntry

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
interface MemoryEntry {
  id: string;
  documentId: string;
  content: string | null;
  summary?: string | null;
  title?: string | null;
  type?: string | null;
  metadata?: Record<string, string | number | boolean> | null;
  createdAt: string | Date;
  updatedAt: string | Date;
  spaceContainerTag?: string | null;
  relation?: 'updates' | 'extends' | 'derives' | null;
  isLatest?: boolean;
  spaceId?: string | null;
}
```

***

## Exports

### Components

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import {
  MemoryGraph,
  GraphCanvas,
  Legend,
  LoadingIndicator,
  NodeDetailPanel,
  SpacesDropdown
} from '@supermemory/memory-graph';
```

### Hooks

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { useGraphData, useGraphInteractions } from '@supermemory/memory-graph';
```

### Constants

```typescript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { colors, GRAPH_SETTINGS, LAYOUT_CONSTANTS } from '@supermemory/memory-graph';
```

***

## Performance

The graph handles hundreds of nodes efficiently through:

* Canvas-based rendering (not DOM elements)
* Viewport culling (only draws visible nodes)
* Level-of-detail optimization (simplifies when zoomed out)
* Change-based rendering (only redraws when state changes)

For very large datasets (1000+ documents), use pagination to load data in chunks.

## Browser support

Works in all modern browsers supporting Canvas 2D API, ES2020, and CSS custom properties. Tested on Chrome, Firefox, Safari, and Edge.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.