I needed a way to show text differences in my Vue 3 apps, so I built this wrapper around the fantastic jsdiff library by @kpdecker. It gives you five different ways to highlight changes between text blocks, from character-level precision to sentence-level overview.
- Works with Vue 3 Composition API
- Five different diff strategies: characters, words, words with spaces, lines, and sentences
- Perfect for text, documents, and prose comparisons
- Easy to customize with CSS variables
- Full TypeScript support
- Lightweight (just a thin wrapper around jsdiff)
- Pass any options that jsdiff supports
npm install vue-diff-text
To run this demo locally: git clone
this repo, cd demo
, npm install
, then npm run dev
Each component uses a different diffing strategy depending on what level of detail you need:
DiffChars - Shows every single character change. Great for catching typos or small edits.
DiffWords - Highlights word-level changes but ignores whitespace. Perfect for most text editing scenarios.
DiffWordsWithSpace - Like DiffWords but also shows whitespace changes. Useful when formatting matters.
DiffLines - Shows entire line changes. Good for comparing plain text files or when you want a high-level overview.
DiffSentences - Highlights sentence-level changes. Nice for prose and document editing.
⚠️ Important: You should import the CSS file for styling to work. It's not mandatory, you CAN implement the classes yourself.
import 'vue-diff-text/dist/style.css'
<template>
<div>
<!-- Pick whichever diff type makes sense for your use case -->
<DiffChars :old-text="oldText" :new-text="newText" />
<DiffWords :old-text="oldText" :new-text="newText" />
<DiffWordsWithSpace :old-text="oldText" :new-text="newText" />
<DiffLines :old-text="oldText" :new-text="newText" />
<DiffSentences :old-text="oldText" :new-text="newText" />
</div>
</template>
<script setup>
import { DiffChars, DiffWords, DiffWordsWithSpace, DiffLines, DiffSentences } from 'vue-diff-text'
import 'vue-diff-text/dist/style.css'
const oldText = "Hello world"
const newText = "Hello Vue world"
</script>
Since this is just a wrapper around jsdiff, you can pass any options that jsdiff supports:
<template>
<div>
<!-- Ignore case differences -->
<DiffWords
:old-text="oldText"
:new-text="newText"
:options="{ ignoreCase: true }"
/>
<!-- Ignore whitespace when comparing lines -->
<DiffLines
:old-text="oldText"
:new-text="newText"
:options="{ ignoreWhitespace: true }"
/>
</div>
</template>
<script setup>
import { DiffWords, DiffLines } from 'vue-diff-text'
import 'vue-diff-text/dist/style.css'
const oldText = "Hello WORLD"
const newText = "hello world"
</script>
All components take the same props:
-
old-text
(required) - The original text -
new-text
(required) - The new text to compare -
options
(optional) - Any options to pass to jsdiff
The options you can pass depend on which diff type you're using. Here are the most common ones:
For most components:
-
ignoreCase: true
- Ignore case differences -
ignoreWhitespace: true
- Ignore whitespace differences
For DiffLines:
-
newlineIsToken: true
- Treat newlines as separate tokens
Check the jsdiff docs for the complete list of what each diff type supports.
You must import the CSS file for styling to work. Add this import to your component or main.js:
import 'vue-diff-text/dist/style.css'
You can then customize the look in two ways:
Just override the CSS variables to change colors:
:root {
--text-diff-added-bg: #e6ffed;
--text-diff-added-color: #1b7332;
--text-diff-removed-bg: #ffe6e6;
--text-diff-removed-color: #d73a49;
--text-diff-removed-decoration: line-through;
}
If you need more control, target these classes. Note that all styles are scoped under .text-diff
:
.text-diff {
white-space: pre-wrap;
word-wrap: break-word;
/* Add your custom container styles here */
}
.text-diff .diff-added {
background-color: #e6ffed;
color: #1b7332;
font-weight: bold;
border-radius: 3px;
padding: 2px 4px;
}
.text-diff .diff-removed {
background-color: #ffe6e6;
color: #d73a49;
text-decoration: line-through;
border-radius: 3px;
padding: 2px 4px;
}
The available classes are:
-
.text-diff
- Main container (each component has this) -
.text-diff .diff-added
- Added text spans -
.text-diff .diff-removed
- Removed text spans
Want to contribute or just mess around with the code? Here's how to get started.
You'll need Node.js 18+ and npm (or yarn, whatever you prefer).
git clone https://github.com/sitefinitysteve/vue-diff-text.git
cd vue-diff-text
npm install
The easiest way to develop is to use the demo app with hot reload:
cd demo
npm run dev
This spins up a dev server (usually at http://localhost:5173) where you can see all the components in action. The demo is set up with Vite aliases so it points directly to the source files - no build step needed.
Just edit the files in src/components/
and your changes will show up instantly.
If you want to test the built version instead:
npm run build
cd demo
npm run dev
When you're ready to build:
npm run build
This creates the dist files (ES module, UMD bundle, TypeScript declarations, and CSS).
The demo folder has a complete Vue 3 app for testing. It lets you:
- Edit text in real-time and see the diffs
- Compare all five diff types side by side
- Test different options
- Try it with longer text blocks
cd demo
npm install # First time only
npm run dev
vue-diff-text/
├── src/
│ ├── components/ # The five diff components
│ └── index.ts # Main entry point
├── demo/ # Test app
├── dist/ # Built files
└── package.json
Available scripts:
-
npm run dev
- Start dev server -
npm run build
- Build for production -
npm run preview
- Preview built version
For the demo (run from demo/
):
-
npm run dev
- Start demo server -
npm run build
- Build demo -
npm run preview
- Preview built demo
- vue ^3.4.21 - Vue 3 framework
- diff ^5.2.0 - The core diffing library by @kpdecker that does all the heavy lifting
Found a bug or want to add a feature? Pull requests are welcome!
- Fork it
- Create your feature branch
- Make your changes
- Test it in the demo app
- Commit and push
- Open a pull request
MIT © Steve McNiven-Scott
Huge thanks to @kpdecker for creating and maintaining jsdiff. This library wouldn't exist without his excellent work on the underlying diffing algorithms.
- GitHub repo
- Issues
- Vue 3 docs
- jsdiff docs
- v-code-diff - For code diffing with syntax highlighting