Vue 3 integration

A rich text editor for Vue 3

yjd is a dependency-free, tree-shakeable rich text editor with no framework baked in. Wrap it in a small composition-API component with full v-model two-way binding and TypeScript types. Ship ~17 KB, not a whole editor framework.

01 — Install

Add the package

One dependency, no peer requirements. The stylesheet is a single import.

terminal
npm i @oix1987/yjd
02 — The component

A reusable v-model component

Create the editor in onMounted and destroy() it in onBeforeUnmount. Emit update:modelValue on change for v-model, and only setContent when the incoming value differs, so typing never resets the caret.

YjdEditor.vue
<script setup>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue';
import yjd from '@oix1987/yjd';
import '@oix1987/yjd/styles.css';   // once in your app

const props = defineProps({ modelValue: String, placeholder: String });
const emit = defineEmits(['update:modelValue']);
const host = ref(null);
let ed;

onMounted(() => {
  ed = new yjd(host.value, {
    content: props.modelValue ?? '',
    placeholder: props.placeholder,
    onChange: (html) => emit('update:modelValue', html),
  });
});
onBeforeUnmount(() => ed?.destroy());

watch(() => props.modelValue, (v) => {
  if (ed && v != null && v !== ed.getContent()) ed.setContent(v);
});
</script>

<template><div ref="host" /></template>
03 — Use it
App.vue
<YjdEditor v-model="html" placeholder="Write…" />
Live

The editor itself

This is a real yjd instance (the same one the component mounts). Type in it. Want it wrapped in actual Vue with v-model? Open the running Vue example.

YjdEditor.vue — live

Why wrap yjd instead of a Vue-only editor

~17 KB, tree-shakeable

Register only the formats you use from the /core entry. No editor framework in the bundle.

Real v-model

Two-way binding via update:modelValue — feels native, no wrapper library.

TypeScript types

Ships index.d.ts — props and options are typed with no extra install.

No lock-in

The same core runs in React, Svelte and vanilla — one editor across your stack.

💡 SSR (Nuxt): the editor touches the DOM, so mount it on the client — onMounted already is, or wrap the component in <client-only>.

Next

Running Vue example · Using React instead? · Playground presets · Full docs