---
title: "Basic Usage"
description: "Learn the fundamental operations for working with Markdown in Tiptap. This guide covers parsing, serialization, and common tasks."
canonical_url: "https://tiptap.dev/docs/editor/markdown/getting-started/basic-usage"
---

# Basic Usage

Learn the fundamental operations for working with Markdown in Tiptap. This guide covers parsing, serialization, and common tasks.

This guide covers the core operations for working with Markdown: parsing Markdown into your editor and serializing editor content back to Markdown.

## Getting Markdown from the Editor

Use `getMarkdown()` to serialize your editor content to Markdown:

```typescript
const markdown = editor.getMarkdown()
console.log(markdown)
// # Hello
//
// This is a **test**.
```

> **Interactive demo:** [Serialize](https://embed.tiptap.dev/preview/Markdown/Serialize)

## Setting Content from Markdown

All content commands support the `contentType` option:

```typescript
// 1. Initial content
const editor = new Editor({
  extensions: [StarterKit, Markdown],
  content: '# Hello World\n\nThis is **markdown**!',
  contentType: 'markdown',
})

// 2. Replace all content
editor.commands.setContent('# New Content', { contentType: 'markdown' })

// 3. Insert at cursor
editor.commands.insertContent('**Bold** text', { contentType: 'markdown' })

// 4. Insert at specific position
editor.commands.insertContentAt(10, '## Heading', { contentType: 'markdown' })

// 5. Replace a range
editor.commands.insertContentAt({ from: 10, to: 20 }, '**Replace**', { contentType: 'markdown' })
```

> **Interactive demo:** [Parse](https://embed.tiptap.dev/preview/Markdown/Parse)

## Using the MarkdownManager Directly

For more control, access the `MarkdownManager` via `editor.markdown`:

```typescript
// Parse Markdown to JSON
const json = editor.markdown.parse('# Hello World')
console.log(json)
// { type: 'doc', content: [...] }

// Serialize JSON to Markdown
const markdown = editor.markdown.serialize(json)
console.log(markdown)
// # Hello World
```

This is useful when working with JSON content outside the editor context.

## GitHub Flavored Markdown (GFM)

Enable GFM for features like tables and task lists:

```typescript
import { Markdown } from '@tiptap/markdown'
import StarterKit from '@tiptap/starter-kit'
import Table from '@tiptap/extension-table'
import TableRow from '@tiptap/extension-table-row'
import TableCell from '@tiptap/extension-table-cell'
import TableHeader from '@tiptap/extension-table-header'
import TaskList from '@tiptap/extension-task-list'
import TaskItem from '@tiptap/extension-task-item'

const editor = new Editor({
  extensions: [
    StarterKit,
    Table,
    TableRow,
    TableCell,
    TableHeader,
    TaskList,
    TaskItem,
    Markdown.configure({
      markedOptions: { gfm: true },
    }),
  ],
})
```

## Inline Formatting

Standard Markdown formatting works automatically:

```typescript
const markdown = `
**bold text** or __bold text__
*italic text* or _italic text_
***bold and italic***
[Link Text](https://example.com)
\`inline code\`
`

editor.commands.setContent(markdown, { contentType: 'markdown' })
const result = editor.getMarkdown() // Formatting preserved
```

## Working with Block Elements

Block elements like headings, lists, and code blocks work as expected:

### Headings

```typescript
const markdown = `
# Heading 1
## Heading 2
### Heading 3
#### Heading 4
##### Heading 5
###### Heading 6
`
```

### Lists

```typescript
// Unordered lists
const markdown = `
- Item 1
- Item 2
  - Nested item 2.1
  - Nested item 2.2
- Item 3
`

// Ordered lists
const markdown = `
1. First item
2. Second item
   1. Nested item 2.1
   2. Nested item 2.2
3. Third item
`
```

### Code Blocks

```typescript
const markdown = `
\`\`\`javascript
function hello() {
  console.log('Hello World')
}
\`\`\`
`
```

### Blockquotes

```typescript
const markdown = `
> This is a blockquote.
> It can span multiple lines.
>
> > And can be nested.
`
```

## Handling HTML in Markdown

The Markdown extension can parse HTML embedded in Markdown using Tiptap's existing `parseHTML` methods:

```typescript
const markdown = `
# Heading

<div class="custom">
  <p>This HTML will be parsed</p>
</div>

Regular **Markdown** continues here.
`

editor.commands.setContent(markdown, { contentType: 'markdown' })
```

The HTML is parsed according to your extensions' `parseHTML` rules, allowing you to support custom HTML nodes.

## Best Practices

**Always use `contentType`** and set it to `markdown` when setting Markdown content (otherwise it's treated as HTML):

```typescript
editor.commands.setContent(markdown, { contentType: 'markdown' })
```

**Include all needed extensions** or content may be lost:

```typescript
const editor = new Editor({
  extensions: [StarterKit, Markdown], // StarterKit covers most common nodes
})
```

**Test round-trip conversion** to ensure your custom Markdown content survives parse → serialize:

```typescript
editor.commands.setContent('# Hello **World**', { contentType: 'markdown' })
const result = editor.getMarkdown() // Should match original
```

## Key Components

### `MarkdownManager`

The `MarkdownManager` class is the core engine that handles parsing and serialization. It:

- Wraps and configures the MarkedJS instance
- Maintains a registry of extension handlers
- Creates the [Lexer](../glossary/#lexer) instance and registers all [Tokenizers](../glossary/#tokenizer).
- Coordinates between Markdown tokens and Tiptap JSON nodes

### `Markdown` extension

The `Markdown` extension is the main extension that you add to your editor. It provides:

- Overrides for all **content-related** commands on the editor to support Markdown input/output
- The `getMarkdown()` method to serialize content as Markdown
- The `setContent()` command with `contentType: 'markdown'` option to parse Markdown input
- Access to the [`MarkdownManager`](#markdownmanager) instance via `editor.markdown`

### Extension Handlers

Each Tiptap extension can provide Markdown support by configuring the extension:

```typescript
const MyExtension = Node.create({
  // ...

  renderMarkdown: (token, helpers) => { /* ... */ },
  parseMarkdown: (node, helpers) => { /* ... */ },
  markdownTokenizer: { /* ... */ },
})
```

The handlers translate between Markdown tokens and Tiptap nodes in both directions and are automatically registered
by the [`MarkdownManager`](../glossary/#markdownmanager), creating [Tokenizers](../glossary/#tokenizer) out of them and registering those to the [Lexer](../glossary/#lexer).

Learn more about:

- [`renderMarkdown`](../advanced-usage/custom-serializing)
- [`parseMarkdown`](../advanced-usage/custom-parsing)
- [`markdownTokenizer`](../advanced-usage/custom-tokenizer)
