Diff

Renders the difference between two code blocks. The first code block is the "before" state, the second is the "after" state.

Split diff

Use mode="split" to show before and after side by side. Lines that match appear on both sides, removed lines are highlighted red on the left, and added lines are highlighted green on the right.

{% diff mode="split" language="javascript" %}
```javascript
import express from 'express';

const app = express();

app.get('/users', (req, res) => {
  const users = db.query('SELECT * FROM users');
  res.json(users);
});

app.listen(3000);
```

```javascript
import express from 'express';

const app = express();
app.use(express.json());

app.get('/users', async (req, res) => {
  const { page = 1, limit = 20 } = req.query;
  const users = await db.query('SELECT * FROM users LIMIT ? OFFSET ?', [limit, (page - 1) * limit]);
  res.json({ users, page, limit });
});

app.listen(3000);
```
{% /diff %}
<div data-rune="diff">
  <meta content="split" data-field="mode">
  <meta content="javascript" data-field="language">
  <div data-name="split-container">
    <div data-name="panel">
      <div data-name="header">Before</div>
      <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]">
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">import express from 'express';</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">const app = express();</span>
        </span>
        <span data-name="line" data-type="empty">
          <span data-name="gutter"> </span>
          <span data-name="line-content"> </span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="remove">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">app.get('/users', (req, res) =&gt; {</span>
        </span>
        <span data-name="line" data-type="remove">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">  const users = db.query('SELECT * FROM users');</span>
        </span>
        <span data-name="line" data-type="remove">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">  res.json(users);</span>
        </span>
        <span data-name="line" data-type="empty">
          <span data-name="gutter"> </span>
          <span data-name="line-content"> </span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">});</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">app.listen(3000);</span>
        </span>
      </pre>
    </div>
    <div data-name="panel">
      <div data-name="header-after">After</div>
      <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]">
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">import express from 'express';</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">const app = express();</span>
        </span>
        <span data-name="line" data-type="add">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">app.use(express.json());</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="add">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">app.get('/users', async (req, res) =&gt; {</span>
        </span>
        <span data-name="line" data-type="add">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">  const { page = 1, limit = 20 } = req.query;</span>
        </span>
        <span data-name="line" data-type="add">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">  const users = await db.query('SELECT * FROM users LIMIT ? OFFSET ?', [limit, (page - 1) * limit]);</span>
        </span>
        <span data-name="line" data-type="add">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">  res.json({ users, page, limit });</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">});</span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript"></span>
        </span>
        <span data-name="line" data-type="equal">
          <span data-name="gutter"></span>
          <span data-name="line-content" data-language="javascript">app.listen(3000);</span>
        </span>
      </pre>
    </div>
  </div>
</div>
Before
import express from 'express';const app = express();  app.get('/users', (req, res) => {  const users = db.query('SELECT * FROM users');  res.json(users);  });app.listen(3000);
After
import express from 'express';const app = express();app.use(express.json());app.get('/users', async (req, res) => {  const { page = 1, limit = 20 } = req.query;  const users = await db.query('SELECT * FROM users LIMIT ? OFFSET ?', [limit, (page - 1) * limit]);  res.json({ users, page, limit });});app.listen(3000);
<div class="rf-diff rf-diff--split" data-mode="split" data-rune="diff" data-density="full">
  <meta content="javascript" data-field="language" />
  <div data-name="split-container" class="rf-diff__split-container">
    <div data-name="panel" class="rf-diff__panel">
      <div data-name="header" class="rf-diff__header">Before</div>
      <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]" class="rf-diff__code"><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">import express from 'express';</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">const app = express();</span></span><span data-name="line" data-type="empty" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"> </span><span data-name="line-content" class="rf-diff__line-content"> </span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">app.get('/users', (req, res) =&gt; {</span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">  const users = db.query('SELECT * FROM users');</span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">  res.json(users);</span></span><span data-name="line" data-type="empty" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"> </span><span data-name="line-content" class="rf-diff__line-content"> </span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">});</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">app.listen(3000);</span></span></pre>
    </div>
    <div data-name="panel" class="rf-diff__panel">
      <div data-name="header-after" class="rf-diff__header-after">After</div>
      <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]" class="rf-diff__code"><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">import express from 'express';</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">const app = express();</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">app.use(express.json());</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">app.get('/users', async (req, res) =&gt; {</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">  const { page = 1, limit = 20 } = req.query;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">  const users = await db.query('SELECT * FROM users LIMIT ? OFFSET ?', [limit, (page - 1) * limit]);</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">  res.json({ users, page, limit });</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">});</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content"></span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter" class="rf-diff__gutter"></span><span data-name="line-content" data-language="javascript" class="rf-diff__line-content">app.listen(3000);</span></span></pre>
    </div>
  </div>
</div>

Unified diff

The default mode shows changes in a single column with line numbers, +/- prefixes, and colored backgrounds.

{% diff mode="unified" language="css" %}
```css
.button {
  display: inline-block;
  padding: 8px 16px;
  background: blue;
  color: white;
  border: none;
  cursor: pointer;
}
```

```css
.button {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.5rem 1rem;
  background: var(--color-primary);
  color: white;
  border: none;
  border-radius: 0.375rem;
  cursor: pointer;
}
```
{% /diff %}
<div data-rune="diff">
  <meta content="unified" data-field="mode">
  <meta content="css" data-field="language">
  <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]">
    <span data-name="line" data-type="equal">
      <span data-name="gutter-num">1</span>
      <span data-name="gutter-num">1</span>
      <span data-name="gutter-prefix"> </span>
      <span data-name="line-content" data-language="css">.button {</span>
    </span>
    <span data-name="line" data-type="remove">
      <span data-name="gutter-num">2</span>
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-prefix">-</span>
      <span data-name="line-content" data-language="css">  display: inline-block;</span>
    </span>
    <span data-name="line" data-type="remove">
      <span data-name="gutter-num">3</span>
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-prefix">-</span>
      <span data-name="line-content" data-language="css">  padding: 8px 16px;</span>
    </span>
    <span data-name="line" data-type="remove">
      <span data-name="gutter-num">4</span>
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-prefix">-</span>
      <span data-name="line-content" data-language="css">  background: blue;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">2</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  display: inline-flex;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">3</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  align-items: center;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">4</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  gap: 0.5rem;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">5</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  padding: 0.5rem 1rem;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">6</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  background: var(--color-primary);</span>
    </span>
    <span data-name="line" data-type="equal">
      <span data-name="gutter-num">5</span>
      <span data-name="gutter-num">7</span>
      <span data-name="gutter-prefix"> </span>
      <span data-name="line-content" data-language="css">  color: white;</span>
    </span>
    <span data-name="line" data-type="equal">
      <span data-name="gutter-num">6</span>
      <span data-name="gutter-num">8</span>
      <span data-name="gutter-prefix"> </span>
      <span data-name="line-content" data-language="css">  border: none;</span>
    </span>
    <span data-name="line" data-type="add">
      <span data-name="gutter-num"> </span>
      <span data-name="gutter-num">9</span>
      <span data-name="gutter-prefix">+</span>
      <span data-name="line-content" data-language="css">  border-radius: 0.375rem;</span>
    </span>
    <span data-name="line" data-type="equal">
      <span data-name="gutter-num">7</span>
      <span data-name="gutter-num">10</span>
      <span data-name="gutter-prefix"> </span>
      <span data-name="line-content" data-language="css">  cursor: pointer;</span>
    </span>
    <span data-name="line" data-type="equal">
      <span data-name="gutter-num">8</span>
      <span data-name="gutter-num">11</span>
      <span data-name="gutter-prefix"> </span>
      <span data-name="line-content" data-language="css">}</span>
    </span>
  </pre>
</div>
11 .button {2 -  display: inline-block;3 -  padding: 8px 16px;4 -  background: blue; 2+  display: inline-flex; 3+  align-items: center; 4+  gap: 0.5rem; 5+  padding: 0.5rem 1rem; 6+  background: var(--color-primary);57   color: white;68   border: none; 9+  border-radius: 0.375rem;710   cursor: pointer;811 }
<div class="rf-diff rf-diff--unified" data-mode="unified" data-rune="diff" data-density="full">
  <meta content="css" data-field="language" />
  <pre data-name="code" data-copy-selector="[data-name=&quot;line-content&quot;]" class="rf-diff__code"><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">1</span><span data-name="gutter-num" class="rf-diff__gutter-num">1</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix"> </span><span data-name="line-content" data-language="css" class="rf-diff__line-content">.button {</span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">2</span><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">-</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  display: inline-block;</span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">3</span><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">-</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  padding: 8px 16px;</span></span><span data-name="line" data-type="remove" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">4</span><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">-</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  background: blue;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">2</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  display: inline-flex;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">3</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  align-items: center;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">4</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  gap: 0.5rem;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">5</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  padding: 0.5rem 1rem;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">6</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  background: var(--color-primary);</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">5</span><span data-name="gutter-num" class="rf-diff__gutter-num">7</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix"> </span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  color: white;</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">6</span><span data-name="gutter-num" class="rf-diff__gutter-num">8</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix"> </span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  border: none;</span></span><span data-name="line" data-type="add" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num"> </span><span data-name="gutter-num" class="rf-diff__gutter-num">9</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix">+</span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  border-radius: 0.375rem;</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">7</span><span data-name="gutter-num" class="rf-diff__gutter-num">10</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix"> </span><span data-name="line-content" data-language="css" class="rf-diff__line-content">  cursor: pointer;</span></span><span data-name="line" data-type="equal" class="rf-diff__line"><span data-name="gutter-num" class="rf-diff__gutter-num">8</span><span data-name="gutter-num" class="rf-diff__gutter-num">11</span><span data-name="gutter-prefix" class="rf-diff__gutter-prefix"> </span><span data-name="line-content" data-language="css" class="rf-diff__line-content">}</span></span></pre>
</div>

Attributes

AttributeTypeDefaultDescription
modestringunifiedDisplay mode: unified, split, or inline
languagestringLanguage for syntax highlighting

Common attributes

All block runes share these attributes for layout and theming.

AttributeTypeDefaultDescription
widthstringcontentPage grid width: content, wide, or full
spacingstringVertical spacing: flush, tight, default, loose, or breathe
insetstringHorizontal padding: flush, tight, default, loose, or breathe
tintstringNamed colour tint from theme configuration
tint-modestringautoColour scheme override: auto, dark, or light
bgstringNamed background preset from theme configuration