> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/excalidraw/excalidraw/llms.txt
> Use this file to discover all available pages before exploring further.

# Element Utilities

> Utility functions for manipulating and working with Excalidraw elements

# Element Utilities

Utility functions for creating, mutating, and working with Excalidraw elements.

## Import

```jsx theme={null}
import {
  // Element creation
  newElement,
  newTextElement,
  newLinearElement,
  newArrowElement,
  newImageElement,
  newFrameElement,
  
  // Element mutation
  mutateElement,
  newElementWith,
  bumpVersion,
  
  // Element queries
  getNonDeletedElements,
  getSceneVersion,
  hashElementsVersion,
  hashString,
  
  // Element bounds
  getElementAbsoluteCoords,
  getElementBounds,
  getCommonBounds,
  getVisibleSceneBounds,
  
  // Bounding box utilities
  elementsOverlappingBBox,
  isElementInsideBBox,
  elementPartiallyOverlapsWithOrContainsBBox,
  
  // Data utilities
  getDataURL,
  
  // Library utilities
  parseLibraryTokensFromUrl,
  useHandleLibrary,
  
  // Text utilities
  setCustomTextMetricsProvider,
  
  // Types
  CaptureUpdateAction,
} from "@excalidraw/excalidraw";
```

## Element Creation

### newElement

Creates a new generic Excalidraw element.

```typescript theme={null}
function newElement(
  opts: {
    type: ExcalidrawGenericElement["type"];
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawGenericElement>
```

<ParamField path="opts.type" type="string" required>
  Element type (e.g., "rectangle", "ellipse", "diamond")
</ParamField>

<ParamField path="opts.x" type="number" required>
  X coordinate of the element
</ParamField>

<ParamField path="opts.y" type="number" required>
  Y coordinate of the element
</ParamField>

<ParamField path="opts.width" type="number" default="0">
  Width of the element
</ParamField>

<ParamField path="opts.height" type="number" default="0">
  Height of the element
</ParamField>

<ParamField path="opts.angle" type="Radians" default="0">
  Rotation angle in radians
</ParamField>

<ParamField path="opts.strokeColor" type="string">
  Stroke color for the element
</ParamField>

<ParamField path="opts.backgroundColor" type="string">
  Background fill color
</ParamField>

<ParamField path="opts.fillStyle" type="string">
  Fill style ("solid", "hachure", "cross-hatch")
</ParamField>

<ParamField path="opts.strokeWidth" type="number">
  Width of the stroke
</ParamField>

<ParamField path="opts.roughness" type="number">
  Roughness level for hand-drawn appearance
</ParamField>

<ParamField path="opts.opacity" type="number">
  Opacity value (0-100)
</ParamField>

<ResponseField name="element" type="ExcalidrawElement">
  The newly created element with all properties initialized
</ResponseField>

**Example:**

```typescript theme={null}
import { newElement } from "@excalidraw/excalidraw";

const rectangle = newElement({
  type: "rectangle",
  x: 100,
  y: 100,
  width: 200,
  height: 150,
  strokeColor: "#000000",
  backgroundColor: "#ffffff",
  fillStyle: "hachure",
  strokeWidth: 2,
  roughness: 1,
  opacity: 100,
});
```

### newTextElement

Creates a new text element with automatic dimension calculations.

```typescript theme={null}
function newTextElement(
  opts: {
    text: string;
    fontSize?: number;
    fontFamily?: FontFamilyValues;
    textAlign?: TextAlign;
    verticalAlign?: VerticalAlign;
    containerId?: string | null;
    lineHeight?: number;
    autoResize?: boolean;
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawTextElement>
```

<ParamField path="opts.text" type="string" required>
  Text content to display
</ParamField>

<ParamField path="opts.fontSize" type="number">
  Font size in pixels
</ParamField>

<ParamField path="opts.fontFamily" type="FontFamilyValues">
  Font family identifier (FONT\_FAMILY constant)
</ParamField>

<ParamField path="opts.textAlign" type="'left' | 'center' | 'right'">
  Horizontal text alignment
</ParamField>

<ParamField path="opts.verticalAlign" type="'top' | 'middle'">
  Vertical text alignment
</ParamField>

<ParamField path="opts.containerId" type="string | null">
  ID of container element (for bound text)
</ParamField>

<ParamField path="opts.autoResize" type="boolean" default="true">
  Whether text should auto-resize
</ParamField>

**Example:**

```typescript theme={null}
import { newTextElement, FONT_FAMILY } from "@excalidraw/excalidraw";

const textElement = newTextElement({
  text: "Hello, World!",
  x: 100,
  y: 100,
  fontSize: 20,
  fontFamily: FONT_FAMILY.Virgil,
  textAlign: "center",
  strokeColor: "#000000",
});
```

### newLinearElement

Creates a line or arrow element.

```typescript theme={null}
function newLinearElement(
  opts: {
    type: "line" | "arrow";
    points?: LocalPoint[];
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawLinearElement>
```

<ParamField path="opts.type" type="'line' | 'arrow'" required>
  Type of linear element
</ParamField>

<ParamField path="opts.points" type="LocalPoint[]">
  Array of points \[x, y] defining the line path
</ParamField>

**Example:**

```typescript theme={null}
import { newLinearElement } from "@excalidraw/excalidraw";

const line = newLinearElement({
  type: "line",
  x: 100,
  y: 100,
  points: [
    [0, 0],
    [100, 50],
    [200, 100],
  ],
  strokeColor: "#000000",
});
```

### newArrowElement

Creates an arrow element with optional arrowheads.

```typescript theme={null}
function newArrowElement(
  opts: {
    type: "arrow";
    startArrowhead?: Arrowhead | null;
    endArrowhead?: Arrowhead | null;
    points?: LocalPoint[];
    elbowed?: boolean;
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawArrowElement>
```

<ParamField path="opts.startArrowhead" type="Arrowhead | null">
  Arrowhead style for start point ("arrow", "dot", "bar", etc.)
</ParamField>

<ParamField path="opts.endArrowhead" type="Arrowhead | null">
  Arrowhead style for end point
</ParamField>

<ParamField path="opts.elbowed" type="boolean">
  Whether the arrow should use elbow routing
</ParamField>

**Example:**

```typescript theme={null}
import { newArrowElement } from "@excalidraw/excalidraw";

const arrow = newArrowElement({
  type: "arrow",
  x: 100,
  y: 100,
  points: [
    [0, 0],
    [200, 0],
  ],
  startArrowhead: null,
  endArrowhead: "arrow",
  strokeColor: "#000000",
});
```

### newImageElement

Creates an image element.

```typescript theme={null}
function newImageElement(
  opts: {
    type: "image";
    fileId?: string | null;
    status?: "pending" | "saved" | "error";
    scale?: [number, number];
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawImageElement>
```

<ParamField path="opts.fileId" type="string | null">
  ID of the file in BinaryFiles
</ParamField>

<ParamField path="opts.status" type="'pending' | 'saved' | 'error'">
  Loading status of the image
</ParamField>

<ParamField path="opts.scale" type="[number, number]">
  Scale factors \[x, y] for the image
</ParamField>

### newFrameElement

Creates a frame element for grouping.

```typescript theme={null}
function newFrameElement(
  opts: {
    name?: string;
  } & ElementConstructorOpts
): NonDeleted<ExcalidrawFrameElement>
```

<ParamField path="opts.name" type="string | null">
  Optional name for the frame
</ParamField>

## Element Mutation

### mutateElement

Mutates an existing element with updates and bumps its version.

```typescript theme={null}
function mutateElement<TElement extends ExcalidrawElement>(
  element: TElement,
  elementsMap: ElementsMap,
  updates: ElementUpdate<TElement>,
  options?: {
    isDragging?: boolean;
  }
): TElement
```

<ParamField path="element" type="ExcalidrawElement" required>
  The element to mutate
</ParamField>

<ParamField path="elementsMap" type="ElementsMap" required>
  Map of all elements (for context)
</ParamField>

<ParamField path="updates" type="Partial<TElement>" required>
  Properties to update (excludes 'id' and 'updated')
</ParamField>

<ParamField path="options.isDragging" type="boolean">
  Whether the element is being dragged
</ParamField>

<ResponseField name="element" type="TElement">
  The mutated element with updated version and versionNonce
</ResponseField>

**Example:**

```typescript theme={null}
import { mutateElement } from "@excalidraw/excalidraw";

mutateElement(element, elementsMap, {
  x: 150,
  y: 200,
  width: 300,
});
```

### newElementWith

Creates a new element instance with updates (immutable operation).

```typescript theme={null}
function newElementWith<TElement extends ExcalidrawElement>(
  element: TElement,
  updates: ElementUpdate<TElement>,
  force?: boolean
): TElement
```

<ParamField path="element" type="ExcalidrawElement" required>
  The base element
</ParamField>

<ParamField path="updates" type="Partial<TElement>" required>
  Properties to update
</ParamField>

<ParamField path="force" type="boolean" default="false">
  Force regeneration even if no changes detected
</ParamField>

<ResponseField name="element" type="TElement">
  New element instance with updates applied
</ResponseField>

**Example:**

```typescript theme={null}
import { newElementWith } from "@excalidraw/excalidraw";

const updatedElement = newElementWith(element, {
  backgroundColor: "#ff0000",
  opacity: 80,
});
```

### bumpVersion

Bumps element version, versionNonce, and updated timestamp.

```typescript theme={null}
function bumpVersion<T extends ExcalidrawElement>(
  element: T,
  version?: number
): T
```

<ParamField path="element" type="ExcalidrawElement" required>
  The element to bump
</ParamField>

<ParamField path="version" type="number">
  Optional specific version to set (will be incremented by 1)
</ParamField>

**Example:**

```typescript theme={null}
import { bumpVersion } from "@excalidraw/excalidraw";

bumpVersion(element);
```

## Element Queries

### getNonDeletedElements

Filters out deleted elements from an array.

```typescript theme={null}
function getNonDeletedElements<T extends ExcalidrawElement>(
  elements: readonly T[]
): readonly NonDeleted<T>[]
```

<ParamField path="elements" type="readonly ExcalidrawElement[]" required>
  Array of elements to filter
</ParamField>

<ResponseField name="elements" type="NonDeleted<ExcalidrawElement>[]">
  Array of non-deleted elements
</ResponseField>

**Example:**

```typescript theme={null}
import { getNonDeletedElements } from "@excalidraw/excalidraw";

const activeElements = getNonDeletedElements(allElements);
```

### getSceneVersion

Calculates the scene version by summing element versions.

```typescript theme={null}
function getSceneVersion(elements: readonly ExcalidrawElement[]): number
```

<ParamField path="elements" type="readonly ExcalidrawElement[]" required>
  Elements to calculate version from
</ParamField>

<ResponseField name="version" type="number">
  Sum of all element versions
</ResponseField>

**Note:** This function is deprecated. Use `hashElementsVersion` instead for better performance.

### hashElementsVersion

Generates a hash of elements' versionNonce values using the djb2 algorithm.

```typescript theme={null}
function hashElementsVersion(elements: ElementsMapOrArray): number
```

<ParamField path="elements" type="ElementsMapOrArray" required>
  Elements to hash (array or Map)
</ParamField>

<ResponseField name="hash" type="number">
  Unsigned 32-bit integer hash
</ResponseField>

**Example:**

```typescript theme={null}
import { hashElementsVersion } from "@excalidraw/excalidraw";

const versionHash = hashElementsVersion(elements);
```

### hashString

Hashes a string using the djb2 algorithm.

```typescript theme={null}
function hashString(s: string): number
```

<ParamField path="s" type="string" required>
  String to hash
</ParamField>

<ResponseField name="hash" type="number">
  Unsigned 32-bit integer hash
</ResponseField>

## Element Bounds

### getElementAbsoluteCoords

Gets absolute coordinates of an element in scene coordinates.

```typescript theme={null}
function getElementAbsoluteCoords(
  element: ExcalidrawElement,
  elementsMap: ElementsMap,
  includeBoundText?: boolean
): [number, number, number, number, number, number]
```

<ParamField path="element" type="ExcalidrawElement" required>
  The element to get coordinates for
</ParamField>

<ParamField path="elementsMap" type="ElementsMap" required>
  Map of all elements
</ParamField>

<ParamField path="includeBoundText" type="boolean" default="false">
  Whether to include bound text in calculations
</ParamField>

<ResponseField name="coords" type="[x1, y1, x2, y2, cx, cy]">
  Array containing: \[x1, y1, x2, y2, centerX, centerY]
</ResponseField>

**Example:**

```typescript theme={null}
import { getElementAbsoluteCoords } from "@excalidraw/excalidraw";

const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
  element,
  elementsMap
);
console.log(`Bounds: (${x1}, ${y1}) to (${x2}, ${y2})`);
console.log(`Center: (${cx}, ${cy})`);
```

### getElementBounds

Gets the axis-aligned bounding box for an element.

```typescript theme={null}
function getElementBounds(
  element: ExcalidrawElement,
  elementsMap: ElementsMap,
  nonRotated?: boolean
): Bounds
```

<ParamField path="element" type="ExcalidrawElement" required>
  The element to get bounds for
</ParamField>

<ParamField path="elementsMap" type="ElementsMap" required>
  Map of all elements
</ParamField>

<ParamField path="nonRotated" type="boolean" default="false">
  Whether to get bounds without rotation
</ParamField>

<ResponseField name="bounds" type="[minX, minY, maxX, maxY]">
  Bounding box coordinates
</ResponseField>

### getCommonBounds

Gets the common bounding box for multiple elements.

```typescript theme={null}
function getCommonBounds(
  elements: ElementsMapOrArray,
  elementsMap?: ElementsMap
): Bounds
```

<ParamField path="elements" type="ElementsMapOrArray" required>
  Elements to get common bounds for
</ParamField>

<ParamField path="elementsMap" type="ElementsMap">
  Optional elements map for context
</ParamField>

<ResponseField name="bounds" type="[minX, minY, maxX, maxY]">
  Common bounding box containing all elements
</ResponseField>

**Example:**

```typescript theme={null}
import { getCommonBounds } from "@excalidraw/excalidraw";

const [minX, minY, maxX, maxY] = getCommonBounds(selectedElements);
const width = maxX - minX;
const height = maxY - minY;
```

### getVisibleSceneBounds

Gets the visible bounds of the canvas viewport in scene coordinates.

```typescript theme={null}
function getVisibleSceneBounds(state: {
  scrollX: number;
  scrollY: number;
  width: number;
  height: number;
  zoom: { value: number };
}): SceneBounds
```

<ParamField path="state.scrollX" type="number" required>
  Horizontal scroll offset
</ParamField>

<ParamField path="state.scrollY" type="number" required>
  Vertical scroll offset
</ParamField>

<ParamField path="state.width" type="number" required>
  Canvas width
</ParamField>

<ParamField path="state.height" type="number" required>
  Canvas height
</ParamField>

<ParamField path="state.zoom" type="{ value: number }" required>
  Current zoom value
</ParamField>

<ResponseField name="bounds" type="[sceneX, sceneY, sceneX2, sceneY2]">
  Visible scene bounds
</ResponseField>

## Element Text

### refreshTextDimensions

Recalculates text element dimensions based on content and container.

```typescript theme={null}
function refreshTextDimensions(
  textElement: ExcalidrawTextElement,
  container: ExcalidrawTextContainer | null,
  elementsMap: ElementsMap,
  text?: string
): { text: string; x: number; y: number; width: number; height: number } | undefined
```

<ParamField path="textElement" type="ExcalidrawTextElement" required>
  The text element to refresh
</ParamField>

<ParamField path="container" type="ExcalidrawTextContainer | null" required>
  Container element (if text is bound)
</ParamField>

<ParamField path="elementsMap" type="ElementsMap" required>
  Map of all elements
</ParamField>

<ParamField path="text" type="string">
  Optional text override
</ParamField>

<ResponseField name="dimensions" type="object">
  Updated text, position, and dimensions
</ResponseField>

## Bounding Box Utilities

### elementsOverlappingBBox

Finds elements that overlap with, contain, or are inside a bounding box.

```typescript theme={null}
function elementsOverlappingBBox(opts: {
  elements: readonly NonDeletedExcalidrawElement[];
  bounds: Bounds | ExcalidrawElement;
  errorMargin?: number;
  type: "overlap" | "contain" | "inside";
}): readonly NonDeletedExcalidrawElement[];
```

<ParamField path="elements" type="readonly NonDeletedExcalidrawElement[]" required>
  Elements to check against the bounding box.
</ParamField>

<ParamField path="bounds" type="Bounds | ExcalidrawElement" required>
  Bounding box as `[x1, y1, x2, y2]` or an element to use its bounds.
</ParamField>

<ParamField path="errorMargin" type="number" default="0">
  Safety offset in pixels to expand the bounding box.
</ParamField>

<ParamField path="type" type="'overlap' | 'contain' | 'inside'" required>
  * `overlap`: Elements overlapping or inside bounds
  * `contain`: Elements inside bounds or bounds inside elements
  * `inside`: Elements inside bounds only
</ParamField>

<ResponseField name="elements" type="NonDeletedExcalidrawElement[]">
  Array of elements matching the criteria.
</ResponseField>

**Example:**

```typescript theme={null}
import { elementsOverlappingBBox } from "@excalidraw/excalidraw";

// Find elements overlapping a selection box
const selectedElements = elementsOverlappingBBox({
  elements: allElements,
  bounds: [100, 100, 400, 400],
  type: "overlap",
});

// Find elements completely inside a frame
const elementsInFrame = elementsOverlappingBBox({
  elements: allElements,
  bounds: frameElement,
  type: "inside",
});
```

### isElementInsideBBox

Checks if an element is inside a bounding box.

```typescript theme={null}
function isElementInsideBBox(
  element: NonDeletedExcalidrawElement,
  bbox: Bounds,
  eitherDirection?: boolean
): boolean;
```

<ParamField path="element" type="NonDeletedExcalidrawElement" required>
  Element to check.
</ParamField>

<ParamField path="bbox" type="Bounds" required>
  Bounding box as `[x1, y1, x2, y2]`.
</ParamField>

<ParamField path="eitherDirection" type="boolean" default="false">
  If `true`, also returns `true` if bbox is inside element.
</ParamField>

<ResponseField name="result" type="boolean">
  `true` if element is inside the bounding box.
</ResponseField>

**Example:**

```typescript theme={null}
import { isElementInsideBBox } from "@excalidraw/excalidraw";

const bounds = [0, 0, 500, 500];
const isInside = isElementInsideBBox(element, bounds);

if (isInside) {
  console.log("Element is inside the bounds");
}
```

### elementPartiallyOverlapsWithOrContainsBBox

Checks if an element partially overlaps with or contains a bounding box.

```typescript theme={null}
function elementPartiallyOverlapsWithOrContainsBBox(
  element: NonDeletedExcalidrawElement,
  bbox: Bounds
): boolean;
```

<ParamField path="element" type="NonDeletedExcalidrawElement" required>
  Element to check.
</ParamField>

<ParamField path="bbox" type="Bounds" required>
  Bounding box as `[x1, y1, x2, y2]`.
</ParamField>

<ResponseField name="result" type="boolean">
  `true` if element overlaps or contains the bounding box.
</ResponseField>

**Example:**

```typescript theme={null}
import { elementPartiallyOverlapsWithOrContainsBBox } from "@excalidraw/excalidraw";

const dragBox = [100, 100, 200, 200];
const overlaps = elementPartiallyOverlapsWithOrContainsBBox(element, dragBox);

if (overlaps) {
  console.log("Element should be selected");
}
```

## Data Utilities

### getDataURL

Converts a Blob or File to a Data URL (async).

```typescript theme={null}
function getDataURL(file: Blob | File): Promise<DataURL>;
```

<ParamField path="file" type="Blob | File" required>
  File or Blob to convert.
</ParamField>

<ResponseField name="dataURL" type="DataURL">
  Base64-encoded data URL string.
</ResponseField>

**Example:**

```typescript theme={null}
import { getDataURL } from "@excalidraw/excalidraw";

const file = new File(["Hello"], "test.txt", { type: "text/plain" });
const dataURL = await getDataURL(file);
console.log(dataURL); // "data:text/plain;base64,SGVsbG8="
```

## Library Utilities

### parseLibraryTokensFromUrl

Extracts library installation URL and ID token from the current page URL.

```typescript theme={null}
function parseLibraryTokensFromUrl(): {
  libraryUrl: string;
  idToken: string | null;
} | null;
```

<ResponseField name="result" type="object | null">
  Object with `libraryUrl` and `idToken`, or `null` if not found.
</ResponseField>

**Example:**

```typescript theme={null}
import { parseLibraryTokensFromUrl } from "@excalidraw/excalidraw";

// URL: https://excalidraw.com/#addLibrary=https://example.com/lib.excalidrawlib
const tokens = parseLibraryTokensFromUrl();

if (tokens) {
  console.log("Library URL:", tokens.libraryUrl);
  console.log("ID Token:", tokens.idToken);
}
```

### useHandleLibrary

Hook for handling library loading, updates, and persistence.

```typescript theme={null}
function useHandleLibrary(opts: {
  excalidrawAPI: ExcalidrawImperativeAPI | null;
  validateLibraryUrl?: (url: string) => boolean;
} & (
  | { getInitialLibraryItems?: () => MaybePromise<LibraryItemsSource> }
  | {
      adapter: LibraryPersistenceAdapter;
      migrationAdapter?: LibraryMigrationAdapter;
    }
)): void;
```

<ParamField path="excalidrawAPI" type="ExcalidrawImperativeAPI | null" required>
  Excalidraw API instance.
</ParamField>

<ParamField path="validateLibraryUrl" type="function">
  Custom validator for library installation URLs.

  ```typescript theme={null}
  validateLibraryUrl?: (url: string) => boolean;
  ```
</ParamField>

<ParamField path="adapter" type="LibraryPersistenceAdapter">
  Adapter for persisting library to storage.

  ```typescript theme={null}
  interface LibraryPersistenceAdapter {
    load(metadata: { source: "load" | "save" }): Promise<{
      libraryItems: LibraryItems;
    } | null>;
    save(data: { libraryItems: LibraryItems }): Promise<void>;
  }
  ```
</ParamField>

<ParamField path="migrationAdapter" type="LibraryMigrationAdapter">
  Optional adapter for migrating from legacy storage.

  ```typescript theme={null}
  interface LibraryMigrationAdapter {
    load(): Promise<{ libraryItems: LibraryItems } | null>;
    clear(): Promise<void>;
  }
  ```
</ParamField>

**Example:**

```typescript theme={null}
import { useHandleLibrary } from "@excalidraw/excalidraw";

function MyEditor() {
  const [excalidrawAPI, setExcalidrawAPI] = useState(null);

  useHandleLibrary({
    excalidrawAPI,
    adapter: {
      async load() {
        const data = localStorage.getItem("excalidraw-library");
        return data ? JSON.parse(data) : null;
      },
      async save({ libraryItems }) {
        localStorage.setItem(
          "excalidraw-library",
          JSON.stringify({ libraryItems })
        );
      },
    },
  });

  return <Excalidraw excalidrawAPI={(api) => setExcalidrawAPI(api)} />;
}
```

## Text Utilities

### setCustomTextMetricsProvider

Sets a custom text metrics provider for measuring text dimensions.

```typescript theme={null}
function setCustomTextMetricsProvider(
  provider: (
    text: string,
    font: string
  ) => {
    width: number;
    height: number;
  }
): void;
```

<ParamField path="provider" type="function" required>
  Function that measures text and returns width/height.

  ```typescript theme={null}
  provider: (text: string, font: string) => {
    width: number;
    height: number;
  };
  ```
</ParamField>

**Example:**

```typescript theme={null}
import { setCustomTextMetricsProvider } from "@excalidraw/excalidraw";

// Use a custom text measurement implementation
setCustomTextMetricsProvider((text, font) => {
  const canvas = document.createElement("canvas");
  const ctx = canvas.getContext("2d");
  ctx.font = font;
  
  const metrics = ctx.measureText(text);
  
  return {
    width: metrics.width,
    height: metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent,
  };
});
```

## Types

### CaptureUpdateAction

Enum-like object that controls when element updates are captured in the undo/redo history.

```typescript theme={null}
const CaptureUpdateAction = {
  IMMEDIATELY: "IMMEDIATELY",
  NEVER: "NEVER",
  EVENTUALLY: "EVENTUALLY",
};

type CaptureUpdateActionType = ValueOf<typeof CaptureUpdateAction>;
```

**Values:**

* `IMMEDIATELY` - Updates are immediately undoable. Use for most local updates.
* `NEVER` - Updates never make it to undo/redo stack. Use for remote updates or scene initialization.
* `EVENTUALLY` - Updates will eventually be captured as part of a future increment.

**Example:**

```typescript theme={null}
import { CaptureUpdateAction } from "@excalidraw/excalidraw";

// When updating scene programmatically
excalidrawAPI.updateScene({
  elements: newElements,
  captureUpdate: CaptureUpdateAction.NEVER, // Don't add to undo stack
});

// When updating in response to user action
excalidrawAPI.updateScene({
  elements: modifiedElements,
  captureUpdate: CaptureUpdateAction.IMMEDIATELY, // Allow undo
});
```

## See Also

* [Export Utils](/api/export-utils) - Functions for exporting elements
* [Scene Utils](/api/scene-utils) - Scene management utilities
* [Restore Utils](/api/restore-utils) - Data restoration functions
