Free · MIT · open source
The free text editorthat fits any website.
One <script> and one <textarea> are enough. Image uploads, tables, video, opening and saving Word files: all MIT licensed, with no paid tier.
- No paid tier
- WCAG 2.2 AA
- Safe by default
Type at least 10 words for a score.
- Words
- 33
- Sentences
- 4
- Avg. sentence
- 8.3
- Reading
- 1 min
Readability score: 88/100
This box is a real viveEditor. The number above is worked out again as you type.
Short sentences and common words make a text easy to read. Long sentences pull the score down.
Live demo
Every tool, right on this page.
Insert a table, open a Word file, write a formula, mention someone with @, pick an emoji with :. Type / on an empty line for the block menu.
Features
Everything a writer needs, free.
Every feature is its own package. Heavy parts download only when used.
Clean paste from Word
Word's fake bullets become real nested lists, and lists that Google Docs nests the wrong way are fixed.
Open and save Word and Markdown
Opens .docx, .md, .html and .txt files, saves as Word, Markdown or HTML, and prints.
Find and replace that knows Turkish
Search matches Turkish capitals correctly: “İSTANBUL” finds “istanbul”.
Privacy-first video
YouTube, Vimeo and Spotify links become players. Nothing loads from the provider until someone presses play.
Tables
Merged cells, header rows and column widths, kept in Word files too.
Formulas, footnotes, mentions
LaTeX formulas, footnotes edited in place, @ mentions, emoji and templates come as npm extras.
Install
On your page in a minute.
With one script and no build step, or with typed packages for React, Vue, Svelte and Angular.
The form posts clean HTML under the textarea's name. Always sanitize it again on the server.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/viveeditor@x.y.z/dist/viveeditor.css" />
<script src="https://cdn.jsdelivr.net/npm/viveeditor@x.y.z/dist/viveeditor.classic.iife.js"></script>
<form method="post">
<label for="body">Article</label>
<textarea id="body" name="body" data-editor required></textarea>
</form>Take only the extensions you want; each is its own package.
import { Editor } from '@viveeditor/core'
import { basicExtensions } from '@viveeditor/ext-basic'
import { listExtensions } from '@viveeditor/ext-list'
const editor = await Editor.create(document.querySelector('#editor'), {
extensions: [...basicExtensions, ...listExtensions],
content: '<p>Hello <strong>world</strong></p>',
label: 'Article body',
})
editor.on('change', () => console.log(editor.getHTML()))React 18 and 19. The package is marked "use client".
import { ViveEditor } from '@viveeditor/react'
import 'viveeditor/style.css'
<ViveEditor value={html} onChange={setHtml} locale="en" label="Article body" />Vue 3.5, with v-model.
<script setup>
import { ViveEditor } from '@viveeditor/vue'
import 'viveeditor/style.css'
</script>
<template>
<ViveEditor v-model="html" locale="en" label="Article body" />
</template>Svelte 5, with bind:value.
<script>
import { ViveEditor } from '@viveeditor/svelte'
import 'viveeditor/style.css'
let html = $state('')
</script>
<ViveEditor bind:value={html} locale="en" label="Article body" />Angular 21 and 22, with ngModel or reactive forms.
import { ViveEditorComponent } from '@viveeditor/angular'
@Component({
imports: [ViveEditorComponent, ReactiveFormsModule],
template: `<vive-ng-editor [formControl]="body" locale="en" label="Article body" />`,
})
class ArticleForm {
body = new FormControl('')
}A form field for any page: it posts its value with the form and blocks submit while required and empty.
<script type="module">
import '@viveeditor/element/define'
</script>
<form>
<vive-editor name="body" required locale="en" label="Article body"></vive-editor>
</form>Laravel 12+ and PHP 8.4+: a Blade component, the editor files and the PHP sanitizer.
composer require viveeditor/laravel
php artisan vendor:publish --tag=viveeditor-assets
<head>
@viveeditorScripts
</head>
<x-viveeditor::editor name="body" id="body" :value="old('body', $post->body)" required />
<article>@viveHtml($post->body)</article>Always use an exact version in the CDN address; its add-ons are checked against fingerprints built into that version.
Security and privacy
Safe by default.
The browser is not a security boundary, so viveEditor applies the same rules in the editor and on the server.
The document schema is an allowlist
Unknown markup never reaches the output; pasted, opened and templated content all pass the same rules.
Node and PHP give the same output
@viveeditor/sanitize and viveeditor/sanitizer share one allowlist and one test corpus.
Players are rebuilt
Saved HTML never keeps the address it was given; players are rebuilt from the provider and video id with a fixed sandbox.
Image addresses are checked
Images need https addresses; every address and uploaded file is checked before it reaches the document.
Connects to nothing on its own
The editor loads no web fonts and does no tracking. Even the AI extra talks only to your own server.
Accessible
WCAG 2.2 AA in light and dark themes, full keyboard control and screen reader announcements.
Ready to start?
The docs cover every step from installing to cleaning HTML on the server, using the real API.