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

# Commands

> Commands are the primary way to manipulate content in Tiptap. Learn how to use commands, create chains, and build your own commands.

Commands are functions that manipulate the editor state. They're the primary way you interact with Tiptap to change content, format text, and control the editor.

## Using Commands

All commands are available through `editor.commands`:

```typescript theme={null}
// Set content
editor.commands.setContent('<p>Hello World!</p>')

// Toggle formatting
editor.commands.toggleBold()
editor.commands.toggleItalic()

// Insert content
editor.commands.insertContent('<p>New paragraph</p>')

// Set node type
editor.commands.setParagraph()
editor.commands.setHeading({ level: 1 })
```

Source: `/home/daytona/workspace/source/packages/core/src/Editor.ts:232`

## Command Types

Tiptap provides three ways to execute commands:

<CardGroup cols={3}>
  <Card title="Single Commands" icon="play">
    Execute one command immediately.

    ```typescript theme={null}
    editor.commands.toggleBold()
    ```
  </Card>

  <Card title="Chained Commands" icon="link">
    Execute multiple commands in sequence.

    ```typescript theme={null}
    editor.chain()
      .toggleBold()
      .toggleItalic()
      .run()
    ```
  </Card>

  <Card title="Can Commands" icon="clipboard-check">
    Check if a command can be executed.

    ```typescript theme={null}
    editor.can().toggleBold()
    ```
  </Card>
</CardGroup>

### Single Commands

Single commands execute immediately and return a boolean indicating success:

```typescript theme={null}
const success = editor.commands.toggleBold()

if (success) {
  console.log('Bold was toggled')
} else {
  console.log('Bold could not be toggled')
}
```

Source: `/home/daytona/workspace/source/packages/core/src/CommandManager.ts:28`

### Chained Commands

Chained commands batch multiple operations into a single transaction:

```typescript theme={null}
editor
  .chain()
  .focus()
  .toggleBold()
  .toggleItalic()
  .run()
```

<Warning>
  You **must** call `.run()` at the end of a chain to execute the commands!
</Warning>

Chains stop executing if a command fails:

```typescript theme={null}
// If toggleBold fails, toggleItalic won't run
editor
  .chain()
  .toggleBold() // fails
  .toggleItalic() // won't run
  .run()
```

The chain returns `true` if all commands succeeded, `false` otherwise:

```typescript theme={null}
const success = editor
  .chain()
  .toggleBold()
  .toggleItalic()
  .run()

console.log(success) // true or false
```

Source: `/home/daytona/workspace/source/packages/core/src/CommandManager.ts:59`

### Can Commands

Use `editor.can()` to check if a command can be executed without actually executing it:

```typescript theme={null}
if (editor.can().toggleBold()) {
  console.log('Bold can be toggled')
}

// Disable a button if the command can't run
const isBoldDisabled = !editor.can().toggleBold()
```

You can also chain `can()` commands:

```typescript theme={null}
if (editor.can().chain().toggleBold().toggleItalic().run()) {
  console.log('Both bold and italic can be toggled')
}
```

Source: `/home/daytona/workspace/source/packages/core/src/CommandManager.ts:95`

## Command Categories

### Content Commands

<ResponseField name="setContent" type="(content: string | JSONContent, options?) => boolean">
  Replace the entire document.

  ```typescript theme={null}
  // Set HTML
  editor.commands.setContent('<p>Hello World!</p>')

  // Set JSON
  editor.commands.setContent({
    type: 'doc',
    content: [{ type: 'paragraph', content: [{ type: 'text', text: 'Hello' }] }]
  })

  // Don't emit update event
  editor.commands.setContent('<p>Hello</p>', { emitUpdate: false })
  ```

  Source: `/home/daytona/workspace/source/packages/core/src/commands/setContent.ts:35`
</ResponseField>

<ResponseField name="insertContent" type="(content: string | JSONContent, options?) => boolean">
  Insert content at the current cursor position.

  ```typescript theme={null}
  editor.commands.insertContent('<p>New paragraph</p>')
  ```
</ResponseField>

<ResponseField name="insertContentAt" type="(position: number | Range, content: string | JSONContent) => boolean">
  Insert content at a specific position.

  ```typescript theme={null}
  // Insert at position 10
  editor.commands.insertContentAt(10, '<p>Hello</p>')

  // Insert in a range
  editor.commands.insertContentAt({ from: 0, to: 10 }, '<p>Hello</p>')
  ```
</ResponseField>

<ResponseField name="clearContent" type="(emitUpdate?: boolean) => boolean">
  Clear the entire document.

  ```typescript theme={null}
  editor.commands.clearContent()
  ```
</ResponseField>

### Selection Commands

<ResponseField name="focus" type="(position?: 'start' | 'end' | number | boolean) => boolean">
  Focus the editor.

  ```typescript theme={null}
  // Focus at current position
  editor.commands.focus()

  // Focus at start
  editor.commands.focus('start')

  // Focus at end
  editor.commands.focus('end')

  // Focus at position 10
  editor.commands.focus(10)
  ```
</ResponseField>

<ResponseField name="blur" type="() => boolean">
  Remove focus from the editor.

  ```typescript theme={null}
  editor.commands.blur()
  ```
</ResponseField>

<ResponseField name="setTextSelection" type="(position: number | Range) => boolean">
  Set the text selection.

  ```typescript theme={null}
  // Select position 10
  editor.commands.setTextSelection(10)

  // Select from 0 to 10
  editor.commands.setTextSelection({ from: 0, to: 10 })
  ```
</ResponseField>

<ResponseField name="selectAll" type="() => boolean">
  Select the entire document.

  ```typescript theme={null}
  editor.commands.selectAll()
  ```
</ResponseField>

### Node Commands

<ResponseField name="setNode" type="(typeOrName: string | NodeType, attributes?) => boolean">
  Replace the current node with a different type.

  ```typescript theme={null}
  // Set to paragraph
  editor.commands.setNode('paragraph')

  // Set to heading with level
  editor.commands.setNode('heading', { level: 1 })
  ```
</ResponseField>

<ResponseField name="toggleNode" type="(typeOrName: string | NodeType, toggleTypeOrName: string | NodeType, attributes?) => boolean">
  Toggle between two node types.

  ```typescript theme={null}
  // Toggle between heading and paragraph
  editor.commands.toggleNode('heading', 'paragraph', { level: 1 })
  ```
</ResponseField>

<ResponseField name="deleteNode" type="(typeOrName: string | NodeType) => boolean">
  Delete a specific node.

  ```typescript theme={null}
  editor.commands.deleteNode('image')
  ```
</ResponseField>

<ResponseField name="updateAttributes" type="(typeOrName: string | NodeType | MarkType, attributes: Record<string, any>) => boolean">
  Update attributes of the current node or mark.

  ```typescript theme={null}
  // Update heading level
  editor.commands.updateAttributes('heading', { level: 2 })

  // Update link href
  editor.commands.updateAttributes('link', { href: 'https://example.com' })
  ```
</ResponseField>

### Mark Commands

<ResponseField name="setMark" type="(typeOrName: string | MarkType, attributes?) => boolean">
  Apply a mark to the current selection.

  ```typescript theme={null}
  editor.commands.setMark('bold')
  editor.commands.setMark('link', { href: 'https://example.com' })
  ```
</ResponseField>

<ResponseField name="toggleMark" type="(typeOrName: string | MarkType, attributes?, options?) => boolean">
  Toggle a mark on the current selection.

  ```typescript theme={null}
  // Toggle bold
  editor.commands.toggleMark('bold')

  // Toggle link with attributes
  editor.commands.toggleMark('link', { href: 'https://example.com' })

  // Extend empty mark range
  editor.commands.toggleMark('bold', {}, { extendEmptyMarkRange: true })
  ```

  Source: `/home/daytona/workspace/source/packages/core/src/commands/toggleMark.ts:39`
</ResponseField>

<ResponseField name="unsetMark" type="(typeOrName: string | MarkType, options?) => boolean">
  Remove a mark from the current selection.

  ```typescript theme={null}
  editor.commands.unsetMark('bold')
  editor.commands.unsetMark('link')
  ```
</ResponseField>

<ResponseField name="unsetAllMarks" type="() => boolean">
  Remove all marks from the current selection.

  ```typescript theme={null}
  editor.commands.unsetAllMarks()
  ```
</ResponseField>

### List Commands

<ResponseField name="toggleList" type="(listTypeOrName: string | NodeType, itemTypeOrName: string | NodeType) => boolean">
  Toggle a list.

  ```typescript theme={null}
  editor.commands.toggleList('bulletList', 'listItem')
  editor.commands.toggleList('orderedList', 'listItem')
  ```
</ResponseField>

<ResponseField name="wrapInList" type="(typeOrName: string | NodeType, attributes?) => boolean">
  Wrap the current selection in a list.

  ```typescript theme={null}
  editor.commands.wrapInList('bulletList')
  ```
</ResponseField>

<ResponseField name="liftListItem" type="(typeOrName: string | NodeType) => boolean">
  Lift a list item out of its parent list.

  ```typescript theme={null}
  editor.commands.liftListItem('listItem')
  ```
</ResponseField>

<ResponseField name="sinkListItem" type="(typeOrName: string | NodeType) => boolean">
  Sink a list item into the previous list item.

  ```typescript theme={null}
  editor.commands.sinkListItem('listItem')
  ```
</ResponseField>

## Creating Custom Commands

You can create custom commands in your extensions:

```typescript theme={null}
import { Extension } from '@tiptap/core'

declare module '@tiptap/core' {
  interface Commands<ReturnType> {
    myExtension: {
      insertGreeting: () => ReturnType
      setColor: (color: string) => ReturnType
    }
  }
}

export const MyExtension = Extension.create({
  name: 'myExtension',
  
  addCommands() {
    return {
      insertGreeting: () => ({ commands }) => {
        return commands.insertContent('<p>Hello!</p>')
      },
      
      setColor: (color: string) => ({ commands, tr, state }) => {
        // Access to transaction and state
        return commands.updateAttributes('textStyle', { color })
      },
    }
  },
})
```

### Command Props

Commands receive props that give you access to the editor state:

```typescript theme={null}
addCommands() {
  return {
    myCommand: (arg1, arg2) => ({ commands, editor, state, tr, dispatch, chain, can }) => {
      // commands: Access to all other commands
      // editor: The editor instance
      // state: Current editor state
      // tr: Current transaction
      // dispatch: Function to dispatch the transaction
      // chain: Create a command chain
      // can: Check if commands can run
      
      return true // Return true if successful
    },
  }
}
```

Source: `/home/daytona/workspace/source/packages/core/src/CommandManager.ts:112`

### Real Example: setParagraph

Here's the actual implementation of the `setParagraph` command from the Paragraph extension:

```typescript theme={null}
addCommands() {
  return {
    setParagraph: () => ({ commands }) => {
      return commands.setNode(this.name)
    },
  }
}
```

Source: `/home/daytona/workspace/source/packages/extension-paragraph/src/paragraph.ts:109`

### Real Example: toggleBold

Here's the implementation from the Bold extension:

```typescript theme={null}
addCommands() {
  return {
    setBold: () => ({ commands }) => {
      return commands.setMark(this.name)
    },
    toggleBold: () => ({ commands }) => {
      return commands.toggleMark(this.name)
    },
    unsetBold: () => ({ commands }) => {
      return commands.unsetMark(this.name)
    },
  }
}
```

Source: `/home/daytona/workspace/source/packages/extension-bold/src/bold.tsx:106`

## Advanced Command Usage

### Conditional Execution

```typescript theme={null}
editor
  .chain()
  .focus()
  .command(({ tr, state }) => {
    // Custom command logic
    if (state.selection.empty) {
      return false
    }
    
    // Do something with the transaction
    tr.insertText('Hello')
    
    return true
  })
  .run()
```

### Accessing State in Commands

```typescript theme={null}
const customCommand = () => ({ tr, state, dispatch }) => {
  const { selection } = state
  const { from, to } = selection
  
  // Get selected text
  const text = state.doc.textBetween(from, to)
  
  console.log('Selected text:', text)
  
  if (dispatch) {
    tr.insertText(text.toUpperCase(), from, to)
  }
  
  return true
}

editor.commands.command(customCommand)
```

### Checking Command Success

```typescript theme={null}
const success = editor
  .chain()
  .focus()
  .toggleBold()
  .toggleItalic()
  .run()

if (!success) {
  console.error('Commands failed to execute')
}
```

## Common Command Patterns

### Toggle Formatting

```typescript theme={null}
const toggleBold = () => {
  if (editor.can().toggleBold()) {
    editor.chain().focus().toggleBold().run()
  }
}
```

### Set Heading Level

```typescript theme={null}
const setHeadingLevel = (level: number) => {
  editor
    .chain()
    .focus()
    .toggleHeading({ level })
    .run()
}
```

### Insert Link

```typescript theme={null}
const insertLink = (href: string) => {
  editor
    .chain()
    .focus()
    .extendMarkRange('link')
    .setLink({ href })
    .run()
}
```

### Remove Link

```typescript theme={null}
const removeLink = () => {
  editor
    .chain()
    .focus()
    .extendMarkRange('link')
    .unsetLink()
    .run()
}
```

### Toggle List

```typescript theme={null}
const toggleBulletList = () => {
  editor
    .chain()
    .focus()
    .toggleBulletList()
    .run()
}
```

## TypeScript Types

```typescript theme={null}
import type { 
  SingleCommands, 
  ChainedCommands, 
  CanCommands,
  CommandProps,
} from '@tiptap/core'

// Command function type
type CommandFunction = (props: CommandProps) => boolean

// Declare custom commands
declare module '@tiptap/core' {
  interface Commands<ReturnType> {
    myExtension: {
      myCommand: (arg: string) => ReturnType
    }
  }
}
```

## Best Practices

<Card title="Always Use Chains for Multiple Commands" icon="link">
  Batch multiple commands into a single transaction for better performance and UX.

  ```typescript theme={null}
  // Bad: Multiple transactions
  editor.commands.toggleBold()
  editor.commands.toggleItalic()

  // Good: Single transaction
  editor.chain().toggleBold().toggleItalic().run()
  ```
</Card>

<Card title="Check Before Executing" icon="clipboard-check">
  Use `can()` to check if a command can run before executing it.

  ```typescript theme={null}
  if (editor.can().toggleBold()) {
    editor.commands.toggleBold()
  }
  ```
</Card>

<Card title="Focus Before Editing" icon="bullseye">
  Always focus the editor before running content commands.

  ```typescript theme={null}
  editor.chain().focus().toggleBold().run()
  ```
</Card>

<Card title="Return True on Success" icon="check">
  Custom commands should return `true` if successful, `false` otherwise.

  ```typescript theme={null}
  myCommand: () => ({ commands }) => {
    const success = commands.insertContent('Hello')
    return success
  }
  ```
</Card>

## Related

<CardGroup cols={2}>
  <Card title="Editor" icon="pen-to-square" href="/core-concepts/editor">
    Learn about the Editor class
  </Card>

  <Card title="Extensions" icon="puzzle-piece" href="/core-concepts/extensions">
    Learn how to create commands in extensions
  </Card>

  <Card title="Nodes & Marks" icon="cube" href="/core-concepts/nodes-and-marks">
    Learn about content structure
  </Card>

  <Card title="Schema" icon="diagram-project" href="/core-concepts/schema">
    Learn about the ProseMirror schema
  </Card>
</CardGroup>
