or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-tiptap--core

Headless rich text editor built on ProseMirror with extensible architecture for building custom editors

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@tiptap/core@3.4.x

To install, run

npx @tessl/cli install tessl/npm-tiptap--core@3.4.0

0

# @tiptap/core

1

2

@tiptap/core is a headless rich text editor built on top of ProseMirror. It provides a flexible, extensible architecture for building custom rich text editors with nodes, marks, extensions, and commands. The library is framework-agnostic and can be integrated with React, Vue, Svelte, or used in vanilla JavaScript/TypeScript applications.

3

4

## Package Information

5

6

- **Package Name**: @tiptap/core

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install @tiptap/core @tiptap/pm`

10

- **Peer Dependencies**: @tiptap/pm (ProseMirror packages wrapper)

11

12

## Core Imports

13

14

```typescript

15

import { Editor, Extension, Node, Mark } from '@tiptap/core';

16

```

17

18

For CommonJS:

19

20

```javascript

21

const { Editor, Extension, Node, Mark } = require('@tiptap/core');

22

```

23

24

JSX Runtime (optional):

25

26

```typescript

27

import { createElement, Fragment, h } from '@tiptap/core';

28

```

29

30

## Basic Usage

31

32

```typescript

33

import { Editor, Extension } from '@tiptap/core';

34

35

// Create a basic extension

36

const BasicExtension = Extension.create({

37

name: 'basicExtension',

38

39

addCommands() {

40

return {

41

insertText: (text: string) => ({ commands }) => {

42

return commands.insertContent(text);

43

}

44

};

45

}

46

});

47

48

// Create and mount editor

49

const editor = new Editor({

50

element: document.querySelector('#editor'),

51

content: '<p>Hello World!</p>',

52

extensions: [BasicExtension],

53

onUpdate: ({ editor }) => {

54

console.log('Content updated:', editor.getHTML());

55

}

56

});

57

58

// Use commands

59

editor.commands.insertText('Hello Tiptap!');

60

61

// Chain commands

62

editor

63

.chain()

64

.focus()

65

.insertContent('More content')

66

.run();

67

68

// Check if commands can be executed

69

if (editor.can().insertContent('test')) {

70

editor.commands.insertContent('test');

71

}

72

```

73

74

## Architecture

75

76

@tiptap/core is built around several key components:

77

78

- **Editor**: The central editor instance that manages state, view, extensions, and commands

79

- **Extensions**: Modular functionality that can be added to the editor (non-content features)

80

- **Nodes**: Document content structures (paragraphs, headings, lists, etc.)

81

- **Marks**: Text formatting (bold, italic, links, etc.)

82

- **Commands**: Actions that can be performed on the editor

83

- **Rules**: Input and paste transformation rules for shortcuts and content processing

84

- **Views**: Custom DOM representations for nodes and marks

85

- **Helpers**: Utility functions for document manipulation and querying

86

87

## Capabilities

88

89

### Editor Core

90

91

Central editor class that manages the editor state, extensions, and provides the main API interface.

92

93

```typescript { .api }

94

class Editor {

95

constructor(options: Partial<EditorOptions>);

96

97

// Core properties

98

view: EditorView;

99

state: EditorState;

100

schema: Schema;

101

storage: Storage;

102

isEditable: boolean;

103

isFocused: boolean;

104

isEmpty: boolean;

105

isDestroyed: boolean;

106

isInitialized: boolean;

107

108

// Lifecycle methods

109

mount(element?: Element): Editor;

110

unmount(): Editor;

111

destroy(): void;

112

113

// Command execution

114

commands: SingleCommands;

115

chain(): ChainedCommands;

116

can(): CanCommands;

117

118

// Content methods

119

getHTML(): string;

120

getJSON(): JSONContent;

121

getText(options?: GetTextOptions): string;

122

setOptions(options: Partial<EditorOptions>): void;

123

setEditable(editable: boolean): void;

124

125

// State inspection

126

getAttributes(nameOrType: string | NodeType | MarkType): Record<string, any>;

127

isActive(name: string, attributes?: Record<string, any>): boolean;

128

129

// Content querying

130

$pos(pos: number): NodePos;

131

$node(selector: string, attributes?: Record<string, any>): NodePos | null;

132

$nodes(selector: string, attributes?: Record<string, any>): NodePos[];

133

134

// Plugin management

135

registerPlugin(plugin: Plugin, handlePlugins?: (newPlugin: Plugin, plugins: Plugin[]) => Plugin[]): EditorState;

136

unregisterPlugin(nameOrPluginKey: string | PluginKey | (string | PluginKey)[]): EditorState | undefined;

137

}

138

139

interface EditorOptions {

140

element?: Element;

141

content?: Content;

142

extensions?: Extensions;

143

injectCSS?: boolean;

144

injectNonce?: string;

145

autofocus?: FocusPosition;

146

editable?: boolean;

147

editorProps?: EditorProps;

148

parseOptions?: ParseOptions;

149

enableInputRules?: boolean;

150

enablePasteRules?: boolean;

151

enableCoreExtensions?: boolean | Record<string, boolean>;

152

enableContentCheck?: boolean;

153

emitContentError?: boolean;

154

coreExtensionOptions?: {

155

clipboardTextSerializer?: {

156

blockSeparator?: string;

157

};

158

delete?: {

159

asyncDeleteEvents?: boolean;

160

};

161

};

162

onBeforeCreate?(props: EditorEvents['beforeCreate']): void;

163

onCreate?(props: EditorEvents['create']): void;

164

onMount?(props: EditorEvents['mount']): void;

165

onUnmount?(props: EditorEvents['unmount']): void;

166

onUpdate?(props: EditorEvents['update']): void;

167

onSelectionUpdate?(props: EditorEvents['selectionUpdate']): void;

168

onTransaction?(props: EditorEvents['transaction']): void;

169

onFocus?(props: EditorEvents['focus']): void;

170

onBlur?(props: EditorEvents['blur']): void;

171

onContentError?(props: EditorEvents['contentError']): void;

172

onDestroy?(): void;

173

}

174

```

175

176

[Editor Core](./editor-core.md)

177

178

### Extension System

179

180

Flexible extension system for adding functionality to the editor through Extensions, Nodes, and Marks.

181

182

```typescript { .api }

183

class Extension<Options = any, Storage = any> {

184

static create<O = any, S = any>(config?: Partial<ExtensionConfig<O, S>>): Extension<O, S>;

185

186

configure(options?: Partial<Options>): Extension<Options, Storage>;

187

extend<ExtendedOptions = Options, ExtendedStorage = Storage>(

188

extendedConfig?: Partial<ExtensionConfig<ExtendedOptions, ExtendedStorage>>

189

): Extension<ExtendedOptions, ExtendedStorage>;

190

}

191

192

class Node<Options = any, Storage = any> {

193

static create<O = any, S = any>(config?: Partial<NodeConfig<O, S>>): Node<O, S>;

194

195

configure(options?: Partial<Options>): Node<Options, Storage>;

196

extend<ExtendedOptions = Options, ExtendedStorage = Storage>(

197

extendedConfig?: Partial<NodeConfig<ExtendedOptions, ExtendedStorage>>

198

): Node<ExtendedOptions, ExtendedStorage>;

199

}

200

201

class Mark<Options = any, Storage = any> {

202

static create<O = any, S = any>(config?: Partial<MarkConfig<O, S>>): Mark<O, S>;

203

204

configure(options?: Partial<Options>): Mark<Options, Storage>;

205

extend<ExtendedOptions = Options, ExtendedStorage = Storage>(

206

extendedConfig?: Partial<MarkConfig<ExtendedOptions, ExtendedStorage>>

207

): Mark<ExtendedOptions, ExtendedStorage>;

208

209

static handleExit(options: { editor: Editor; mark: ProseMirrorMark }): boolean;

210

}

211

```

212

213

[Extension System](./extension-system.md)

214

215

### Command System

216

217

Powerful command system for executing, chaining, and validating editor actions.

218

219

```typescript { .api }

220

interface SingleCommands {

221

[key: string]: (attributes?: Record<string, any>) => boolean;

222

}

223

224

interface ChainedCommands {

225

[key: string]: (attributes?: Record<string, any>) => ChainedCommands;

226

run(): boolean;

227

}

228

229

interface CanCommands {

230

[key: string]: (attributes?: Record<string, any>) => boolean;

231

}

232

233

class CommandManager {

234

constructor(props: { editor: Editor; state: EditorState });

235

236

readonly commands: SingleCommands;

237

chain(): ChainedCommands;

238

can(): CanCommands;

239

createChain(startTr?: Transaction, shouldDispatch?: boolean): ChainedCommands;

240

createCan(startTr?: Transaction): CanCommands;

241

}

242

243

interface CommandProps {

244

editor: Editor;

245

tr: Transaction;

246

commands: SingleCommands;

247

can: CanCommands;

248

chain: () => ChainedCommands;

249

state: EditorState;

250

view: EditorView;

251

dispatch: ((tr: Transaction) => void) | undefined;

252

}

253

```

254

255

[Command System](./command-system.md)

256

257

### Document Helpers

258

259

Comprehensive set of helper functions for document manipulation, content generation, and state inspection.

260

261

```typescript { .api }

262

// Content generation

263

function generateHTML(doc: JSONContent, extensions: Extensions): string;

264

function generateJSON(content: string, extensions: Extensions): JSONContent;

265

function generateText(doc: JSONContent | Node, options?: GenerateTextOptions): string;

266

267

// Document creation

268

function createDocument(

269

content: Content,

270

schema: Schema,

271

parseOptions?: ParseOptions

272

): ProseMirrorNode;

273

function createNodeFromContent(

274

content: Content,

275

schema: Schema,

276

options?: CreateNodeFromContentOptions

277

): ProseMirrorNode | ProseMirrorNode[];

278

279

// Content queries

280

function findChildren(

281

node: ProseMirrorNode,

282

predicate: (child: ProseMirrorNode) => boolean,

283

descend?: boolean

284

): NodeWithPos[];

285

function findChildrenInRange(

286

node: ProseMirrorNode,

287

range: { from: number; to: number },

288

predicate: (child: ProseMirrorNode) => boolean,

289

descend?: boolean

290

): NodeWithPos[];

291

292

// State inspection

293

function isActive(

294

state: EditorState,

295

name?: string | NodeType | MarkType,

296

attributes?: Record<string, any>

297

): boolean;

298

function getAttributes(

299

state: EditorState,

300

nameOrType: string | NodeType | MarkType

301

): Record<string, any>;

302

```

303

304

[Document Helpers](./document-helpers.md)

305

306

### Rule Systems

307

308

Input and paste rule systems for creating shortcuts and transforming content on input or paste.

309

310

```typescript { .api }

311

class InputRule {

312

constructor(config: {

313

find: RegExp | ((value: string) => RegExpMatchArray | null);

314

handler: (props: {

315

state: EditorState;

316

range: { from: number; to: number };

317

match: RegExpMatchArray;

318

commands: SingleCommands;

319

chain: () => ChainedCommands;

320

can: () => CanCommands;

321

}) => void | null;

322

});

323

}

324

325

class PasteRule {

326

constructor(config: {

327

find: RegExp | ((value: string) => RegExpMatchArray | null);

328

handler: (props: {

329

state: EditorState;

330

range: { from: number; to: number };

331

match: RegExpMatchArray;

332

commands: SingleCommands;

333

chain: () => ChainedCommands;

334

can: () => CanCommands;

335

pastedText: string;

336

dropEvent?: DragEvent;

337

}) => void | null;

338

});

339

}

340

```

341

342

[Rule Systems](./rule-systems.md)

343

344

### JSX Runtime Support

345

346

Built-in JSX runtime support for creating custom extensions and components using JSX syntax.

347

348

```typescript { .api }

349

/**

350

* Create JSX elements for use in extensions

351

* @param type - Element type or component

352

* @param props - Element properties

353

* @param children - Child elements

354

* @returns JSX element

355

*/

356

function createElement(

357

type: string | Component,

358

props: Record<string, any> | null,

359

...children: any[]

360

): JSXElement;

361

362

/**

363

* JSX Fragment component for wrapping multiple elements

364

*/

365

const Fragment: ComponentType;

366

367

/**

368

* Alias for createElement (h stands for hyperscript)

369

*/

370

const h: typeof createElement;

371

```

372

373

**Usage Examples:**

374

375

```typescript

376

import { createElement, Fragment, h } from '@tiptap/core';

377

378

// Using createElement directly

379

const element = createElement('div', { className: 'editor-toolbar' },

380

createElement('button', { onClick: () => editor.chain().focus().toggleBold().run() }, 'Bold'),

381

createElement('button', { onClick: () => editor.chain().focus().toggleItalic().run() }, 'Italic')

382

);

383

384

// Using JSX syntax (with proper JSX transform)

385

const toolbar = (

386

<div className="editor-toolbar">

387

<button onClick={() => editor.chain().focus().toggleBold().run()}>

388

Bold

389

</button>

390

<button onClick={() => editor.chain().focus().toggleItalic().run()}>

391

Italic

392

</button>

393

</div>

394

);

395

396

// Using Fragment

397

const multipleElements = (

398

<Fragment>

399

<p>First paragraph</p>

400

<p>Second paragraph</p>

401

</Fragment>

402

);

403

404

// Using h (hyperscript style)

405

const hyperscriptElement = h('div', { id: 'editor' },

406

h('p', null, 'Content goes here')

407

);

408

409

// In custom extensions

410

const CustomExtension = Extension.create({

411

name: 'customExtension',

412

413

addNodeView() {

414

return ({ node, getPos, editor }) => {

415

const dom = createElement('div', {

416

className: 'custom-node',

417

'data-type': node.type.name

418

}, node.textContent);

419

420

return { dom };

421

};

422

}

423

});

424

```

425

426

### Utilities

427

428

Collection of utility functions for type checking, object manipulation, and platform detection.

429

430

```typescript { .api }

431

// Type guards

432

function isFunction(value: unknown): value is Function;

433

function isString(value: unknown): value is string;

434

function isNumber(value: unknown): value is number;

435

function isPlainObject(value: unknown): value is Record<string, any>;

436

437

// Object utilities

438

function mergeAttributes(...attributes: Record<string, any>[]): Record<string, any>;

439

function mergeDeep(target: Record<string, any>, source: Record<string, any>): Record<string, any>;

440

441

// Platform detection

442

function isAndroid(): boolean;

443

function isiOS(): boolean;

444

function isMacOS(): boolean;

445

446

// DOM utilities

447

function elementFromString(html: string): Element;

448

function createStyleTag(css: string, nonce?: string): HTMLStyleElement;

449

```

450

451

[Utilities](./utilities.md)

452

453

## Types

454

455

```typescript { .api }

456

// Core types

457

type Extensions = AnyExtension[];

458

type AnyExtension = Extension<any, any> | Node<any, any> | Mark<any, any>;

459

460

interface JSONContent {

461

type?: string;

462

attrs?: Record<string, any>;

463

content?: JSONContent[];

464

marks?: {

465

type: string;

466

attrs?: Record<string, any>;

467

}[];

468

text?: string;

469

}

470

471

interface NodeWithPos {

472

node: ProseMirrorNode;

473

pos: number;

474

}

475

476

// Event types

477

interface EditorEvents {

478

beforeCreate: { editor: Editor };

479

create: { editor: Editor };

480

mount: { editor: Editor };

481

unmount: { editor: Editor };

482

update: { editor: Editor; transaction: Transaction; appendedTransactions: Transaction[] };

483

selectionUpdate: { editor: Editor; transaction: Transaction };

484

transaction: { editor: Editor; transaction: Transaction };

485

focus: { editor: Editor; event: FocusEvent; transaction: Transaction };

486

blur: { editor: Editor; event: FocusEvent; transaction: Transaction };

487

contentError: {

488

editor: Editor;

489

error: Error;

490

disableCollaboration: () => void;

491

};

492

}

493

494

// Configuration types

495

interface ExtensionConfig<Options = any, Storage = any> {

496

name: string;

497

defaultOptions?: Options;

498

addStorage?(): Storage;

499

addCommands?(): Commands;

500

addKeymap?(): Record<string, any>;

501

addInputRules?(): InputRule[];

502

addPasteRules?(): PasteRule[];

503

addGlobalAttributes?(): GlobalAttributes[];

504

addNodeView?(): NodeViewRenderer;

505

onCreate?(this: { options: Options; storage: Storage }): void;

506

onUpdate?(this: { options: Options; storage: Storage }): void;

507

onDestroy?(this: { options: Options; storage: Storage }): void;

508

}

509

```