# How DrawDB Implements Cloud Save and Sharing via GitHub Gists

> Learn how DrawDB uses GitHub Gists for cloud save and sharing. Discover its REST API wrapper for seamless diagram management without backend infrastructure.

- Repository: [drawDB/drawdb](https://github.com/drawdb-io/drawdb)
- Tags: internals
- Published: 2026-08-11

---

**DrawDB stores database diagrams in the cloud by treating each diagram as a GitHub Gist, using a lightweight REST API wrapper to create, update, version, and share JSON files without maintaining a dedicated backend infrastructure.**

DrawDB is an open-source database diagramming tool that leverages GitHub's public Gist API to provide serverless persistence and collaboration features. By mapping each diagram to a version-controlled Gist, the application eliminates infrastructure costs while inheriting GitHub's native revision history and public sharing capabilities. The implementation centers on a thin API abstraction layer that treats [`diagram.json`](https://github.com/drawdb-io/drawdb/blob/main/diagram.json) and [`share.json`](https://github.com/drawdb-io/drawdb/blob/main/share.json) files as the single source of truth for diagram state and accessibility.

## Core API Wrapper in [`src/api/gists.js`](https://github.com/drawdb-io/drawdb/blob/main/src/api/gists.js)

The cloud integration resides in [`src/api/gists.js`](https://github.com/drawdb-io/drawdb/blob/main/src/api/gists.js), which exports a set of asynchronous functions wrapping the GitHub Gist REST API via **axios**. This module defines two critical filename constants that determine how data is organized within each Gist:

```js
export const VERSION_FILENAME = "diagram.json";
export const SHARE_FILENAME   = "share.json";

```

The module exposes seven primary operations:

- **`create(content)`** – POSTs to `/gists` to initialize a new diagram, storing the JSON payload in `VERSION_FILENAME` and returning the generated `gistId`.
- **`get(gistId)`** – Retrieves the current state of a Gist, including all files and metadata.
- **`patch(gistId, filename, content)`** – Updates a specific file within an existing Gist, used for both diagram updates and sharing.
- **`del(gistId)`** – Permanently deletes the Gist and all associated versions.
- **`getCommits(gistId, perPage, page)`** – Fetches the commit history for version tracking.
- **`getVersion(gistId, sha)`** – Retrieves a specific historical snapshot using the commit SHA.
- **`compare(gistId, file, versionA, versionB)`** – Generates diffs between two versions of a file.

## State Management with `DiagramContext`

The application maintains cloud synchronization state through the `IdContext` defined in [`src/context/DiagramContext.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/context/DiagramContext.jsx). This context provider stores the current `gistId`, the active version SHA, and setter functions that trigger API calls. Components throughout the editor consume this context to determine whether to initiate a `create` operation for new diagrams or `patch` operations for existing ones.

## Saving Diagrams to the Cloud

When a user initiates a save operation from [`src/components/Workspace.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/components/Workspace.jsx), the application checks for an existing `gistId` in the context. If absent, it invokes `create()` to generate a new Gist, storing the returned identifier for future updates. For subsequent saves, [`Workspace.jsx`](https://github.com/drawdb-io/drawdb/blob/main/Workspace.jsx) calls `patch(gistId, VERSION_FILENAME, diagramToString())` to overwrite the [`diagram.json`](https://github.com/drawdb-io/drawdb/blob/main/diagram.json) file with the current editor state.

## Version Control Implementation

The version history panel in [`src/components/EditorHeader/SideSheet/Versions.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/components/EditorHeader/SideSheet/Versions.jsx) leverages GitHub's native versioning capabilities. The component calls `getCommits()` to retrieve the chronological history of changes, then uses `getVersion()` with specific commit SHAs to fetch historical snapshots. When a user selects a previous version, the application hydrates the editor by loading that specific file content. An in-memory cache prevents redundant network requests for previously loaded commits.

## Public Sharing via Gist Files

The sharing mechanism in [`src/components/EditorHeader/Modal/Share.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/components/EditorHeader/Modal/Share.jsx) utilizes the `SHARE_FILENAME` constant to enable public access. When sharing is activated, the component writes a JSON payload to [`share.json`](https://github.com/drawdb-io/drawdb/blob/main/share.json) within the existing Gist using `patch()`. The application then generates a public URL following the pattern:

```js
const baseUrl = window.location.origin + "/editor?shareId=" + gistId;

```

Recipients opening this URL trigger a `get(gistId)` call that reads the shared file and populates the workspace, enabling collaboration without requiring authentication.

## Practical Implementation Examples

**Creating a new cloud-backed diagram:**

```js
import { create } from "@/api/gists";

async function saveNewDiagram(diagram) {
  const content = JSON.stringify(diagram, null, 2);
  const { gistId } = await create(content);
  setGistId(gistId); // Store in context for subsequent updates
}

```

**Updating an existing diagram:**

```js
import { patch } from "@/api/gists";

async function updateDiagram(gistId, diagram) {
  const content = JSON.stringify(diagram, null, 2);
  await patch(gistId, "diagram.json", content);
}

```

**Loading a shared diagram:**

```js
import { get } from "@/api/gists";

async function loadSharedDiagram(gistId) {
  const { files } = await get(gistId);
  const diagramJson = files["diagram.json"].content;
  return JSON.parse(diagramJson);
}

```

**Retrieving version history:**

```js
import { getCommits, getVersion } from "@/api/gists";

async function listVersions(gistId) {
  const { commits } = await getCommits(gistId);
  return Promise.all(
    commits.map(c => getVersion(gistId, c.version))
  );
}

```

## Summary

- DrawDB uses GitHub Gists as a serverless persistence layer, storing diagrams as JSON files within Gists to eliminate backend infrastructure requirements.
- The [`src/api/gists.js`](https://github.com/drawdb-io/drawdb/blob/main/src/api/gists.js) module provides a typed interface over the GitHub REST API, handling create, read, update, delete, and versioning operations through seven core functions.
- State management via `DiagramContext` tracks the active `gistId` and version history across the application, coordinating saves through [`Workspace.jsx`](https://github.com/drawdb-io/drawdb/blob/main/Workspace.jsx).
- Version control leverages Git's underlying machinery through `getCommits()` and `getVersion()`, providing native diff capabilities without custom implementation.
- Public sharing writes to a dedicated [`share.json`](https://github.com/drawdb-io/drawdb/blob/main/share.json) file and generates query-parameter-based URLs that load diagrams directly via `shareId` parameters.

## Frequently Asked Questions

### How does DrawDB handle version history without a custom backend?

DrawDB leverages GitHub's built-in versioning system by calling `getCommits()` and `getVersion()` from [`src/api/gists.js`](https://github.com/drawdb-io/drawdb/blob/main/src/api/gists.js). Each time `patch()` updates the [`diagram.json`](https://github.com/drawdb-io/drawdb/blob/main/diagram.json) file, GitHub automatically creates a new commit. The application retrieves these commits to display a chronological history, allowing users to restore any previous state by loading the file content from a specific commit SHA.

### What files are created inside a DrawDB GitHub Gist?

Each DrawDB Gist contains at least one file named [`diagram.json`](https://github.com/drawdb-io/drawdb/blob/main/diagram.json) (defined by `VERSION_FILENAME`), which stores the complete diagram state. When public sharing is enabled, the application adds a second file named [`share.json`](https://github.com/drawdb-io/drawdb/blob/main/share.json) (defined by `SHARE_FILENAME`) that contains a snapshot of the diagram intended for public distribution.

### How does the sharing mechanism work technically?

When a user clicks share in [`src/components/EditorHeader/Modal/Share.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/components/EditorHeader/Modal/Share.jsx), the application calls `patch(gistId, SHARE_FILENAME, diagramContent)` to write the current diagram to [`share.json`](https://github.com/drawdb-io/drawdb/blob/main/share.json). The modal then constructs a URL with the format `https://drawdb.app/editor?shareId={gistId}`. When another user visits this URL, the application extracts the `shareId`, calls `get(gistId)`, and loads the diagram from the Gist files into the editor workspace.

### Where is the gistId stored during an editing session?

The current `gistId` is stored in the `IdContext` provided by [`src/context/DiagramContext.jsx`](https://github.com/drawdb-io/drawdb/blob/main/src/context/DiagramContext.jsx). This context wraps the application and makes the identifier available to components like [`Workspace.jsx`](https://github.com/drawdb-io/drawdb/blob/main/Workspace.jsx) for save operations and [`Versions.jsx`](https://github.com/drawdb-io/drawdb/blob/main/Versions.jsx) for history retrieval. The ID persists only for the duration of the session unless explicitly saved to browser storage or the URL query parameters.