vue-diff-text
v1.3.0
Published
Vue 3 components to display text and HTML differences with multiple diff strategies.
Maintainers
Readme
Vue Diff Text
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.
⚠️ Important: This library is designed for text and paragraph comparisons, not code diffing. If you need to compare code with syntax highlighting, use v-code-diff instead.
What you get
- Works with Vue 3 Composition API
- Six different diff strategies: characters, words, words with spaces, lines, sentences, and HTML
- 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
Installation
npm install vue-diff-textDemo

To run this demo locally: git clone this repo, cd demo, npm install, then npm run dev
The six components
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.
DiffHtml - Compares HTML content and highlights markup differences. Perfect for rich text editing and HTML content changes.
How to use it
⚠️ 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'
Basic example
<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" />
<DiffHtml :old-text="oldHtml" :new-text="newHtml" />
</div>
</template>
<script setup>
import { DiffChars, DiffWords, DiffWordsWithSpace, DiffLines, DiffSentences, DiffHtml } from 'vue-diff-text'
import 'vue-diff-text/dist/style.css'
const oldText = "Hello world"
const newText = "Hello Vue world"
const oldHtml = '<p>Welcome to our <strong>website</strong>!</p>'
const newHtml = '<p>Welcome to our <strong>amazing website</strong>!</p>'
</script>Passing options
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>Props
All components take the same props:
old-text(required) - The original textnew-text(required) - The new text to compareoptions(optional) - Any options to pass to jsdiff
Options
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 differencesignoreWhitespace: 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.
Styling
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:
CSS variables (easiest)
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;
}Direct CSS classes
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
Note: The DiffHtml component uses the same CSS classes (.diff-added and .diff-removed) as the other components for consistent styling.
Development
Want to contribute or just mess around with the code? Here's how to get started.
Setup
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 installWorking on it
The easiest way to develop is to use the demo app with hot reload:
cd demo
npm run devThis 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 devBuilding
When you're ready to build:
npm run buildThis creates the dist files (ES module, UMD bundle, TypeScript declarations, and CSS).
Testing
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 devProject layout
vue-diff-text/
├── src/
│ ├── components/ # The five diff components
│ └── index.ts # Main entry point
├── demo/ # Test app
├── dist/ # Built files
└── package.jsonAvailable scripts:
npm run dev- Start dev servernpm run build- Build for productionnpm run preview- Preview built version
For the demo (run from demo/):
npm run dev- Start demo servernpm run build- Build demonpm run preview- Preview built demo
Dependencies
- vue ^3.4.21 - Vue 3 framework
- diff ^5.2.0 - The core diffing library by @kpdecker that does all the heavy lifting
- diffblazer ^1.0.0 - Fast HTML diffing library used by the DiffHtml component
Contributing
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
License
MIT © Steve McNiven-Scott
Thanks
Huge thanks to @kpdecker for creating and maintaining jsdiff. This library wouldn't exist without his excellent work on the underlying diffing algorithms.
Links
- GitHub repo
- Issues
- Vue 3 docs
- jsdiff docs
- v-code-diff - For code diffing with syntax highlighting
