GrapesJS TypeScript — Integration Guide

Full type safety for your GrapesJS editor, plugins, and components

TypeScript Workflow

Ship a safer GrapesJS editor with fully typed APIs

This guide focuses on practical implementation: strict typing for editor lifecycle, plugin contracts, and custom component definitions your team can maintain long-term.

Type source

Built-in v1.x

Recommended mode

strict: true

Use case

Prod editors

Key GrapesJS types you will use daily

Editor

The main editor instance. Use it for lifecycle events, managers, and command execution.

Component

Represents a node in the canvas tree. Useful for typed event handlers and custom traits.

Block

A draggable building block. Type-safe block definitions reduce runtime content mistakes.

ComponentDefinition

Used when registering new component types through ComponentManager.addType().

ComponentProperties

Strongly types defaults and traits so team members reuse the same component contract.

StorageManager

Covers storage config and operations for local or remote persistence workflows.

Step 01

Start with strict TypeScript

Enable strict mode and noImplicitAny before writing editor logic to catch plugin and component mistakes early.

Step 02

Type your editor lifecycle

Use Editor | null for initialization flow and add guards before calling manager APIs from async callbacks.

Step 03

Create typed plugin contracts

Define option interfaces with defaults so plugin APIs stay stable across projects and versions.

Step 04

Ship reusable typed components

Standardize component traits and defaults with shared TypeScript types to keep teams aligned.

Typing the editor instance and events

Keep editor initialization and event flow typed from day one. This catches invalid manager calls and event payload errors early.

  • 1. Use Editor | null during initialization.
  • 2. Type event payloads like Component.
  • 3. Type manager collections when reading blocks/components.
editor-types.ts
import grapesjs from 'grapesjs';
import type { Editor, Component, Block } from 'grapesjs';

// Typed editor instance
let editor: Editor | null = null;

editor = grapesjs.init({
  container: '#gjs',
  storageManager: false,
});

// Typed event handlers
editor.on('component:add', (component: Component) => {
  console.log('Added component:', component.get('type'));
});

// Typed block access
const blockManager = editor.BlockManager;
const blocks: Block[] = blockManager.getAll().models;

Writing a typed GrapesJS plugin

Define plugin option interfaces and defaults to make your extension safe for teams and predictable across releases.

  • 1. Create explicit option interfaces.
  • 2. Use defaults to avoid undefined branches.
  • 3. Keep plugin APIs backward compatible.
plugin.ts
import type { Editor } from 'grapesjs';

interface MyPluginOptions {
  apiKey?: string;
  debug?: boolean;
}

const myPlugin = (editor: Editor, opts: MyPluginOptions = {}) => {
  const { apiKey = '', debug = false } = opts;

  editor.BlockManager.add('custom-block', {
    label: 'Custom Block',
    category: 'Custom',
    content: '<div class="custom-block">Custom content</div>',
  });

  if (debug) {
    console.log('Plugin initialized with API key:', apiKey);
  }
};

export default myPlugin;

Typed custom component definition

Typed component definitions reduce runtime trait errors and help product teams create reusable content models.

  • 1. Type defaults with ComponentProperties.
  • 2. Keep trait names stable and documented.
  • 3. Register component types with clear IDs.
components.ts
import type { ComponentDefinition, ComponentProperties } from 'grapesjs';

// Typed component definition
const heroComponent: ComponentDefinition = {
  model: {
    defaults: {
      tagName: 'section',
      draggable: true,
      droppable: false,
      attributes: { class: 'hero-section' },
      traits: [
        { type: 'text', name: 'headline', label: 'Headline' },
        { type: 'text', name: 'subheadline', label: 'Subheadline' },
      ],
    } as ComponentProperties,
  },
};

editor.ComponentManager.addType('hero', heroComponent);

Pre-launch TypeScript quality checklist

No usage of @types/grapesjs in v1.x projects
Editor instance narrowed before every manager call
Plugin options validated and defaulted
Component traits typed and documented
Build passes with strict mode enabled
Storage payload shape versioned

GrapesJS TypeScript FAQ

Continue learning

TypeScript-compatible plugins on GJS.Market

All premium plugins include TypeScript definitions for safer and faster integration.

Browse plugins