OverviewWhy TypeScriptFeaturesFrameworksAPIDemosGetting startedPricingDownload

Framework guides

One typed call, every framework.

createRichTextEditor attaches to a container element and resolves to a typed RichTextEditorInstance. That fits any framework — you just call it in the right lifecycle hook and tear the editor down on unmount.

React

Mount in an effect, into a ref'd div.

Create the editor in useEffect against a ref element and destroy it in the cleanup. Keep the host a plain <div>: if you set its content with dangerouslySetInnerHTML, React re-applies that HTML on re-render and wipes the live editor.

import { useEffect, useRef } from "react";
import {
  createRichTextEditor,
  type RichTextEditorInstance,
} from "ts-rich-text-editor";

export function Editor() {
  const hostRef = useRef<HTMLDivElement>(null);
  const editorRef = useRef<RichTextEditorInstance | null>(null);

  useEffect(() => {
    let disposed = false;
    createRichTextEditor(hostRef.current!, { height: "480px" }).then((editor) => {
      if (disposed) { editor.destroy?.(); return; }
      editorRef.current = editor;
    });
    return () => {
      disposed = true;
      editorRef.current?.destroy?.();
    };
  }, []);

  // Mount into a plain div. Do NOT feed the host with
  // dangerouslySetInnerHTML — React would re-apply it and wipe the editor.
  return <div ref={hostRef} />;
}

Vue

Create in onMounted, destroy in onBeforeUnmount.

Bind a template ref, await the editor once the element exists, and dispose it on teardown.

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from "vue";
import {
  createRichTextEditor,
  type RichTextEditorInstance,
} from "ts-rich-text-editor";

const host = ref<HTMLDivElement | null>(null);
let editor: RichTextEditorInstance | null = null;

onMounted(async () => {
  editor = await createRichTextEditor(host.value!, { height: "480px" });
});
onBeforeUnmount(() => editor?.destroy?.());
</script>

<template>
  <div ref="host"></div>
</template>

Angular

Use ngAfterViewInit with a @ViewChild host.

The view child gives you the native element; create the editor there and destroy it in ngOnDestroy.

import {
  AfterViewInit, OnDestroy, Component, ElementRef, ViewChild,
} from "@angular/core";
import {
  createRichTextEditor,
  type RichTextEditorInstance,
} from "ts-rich-text-editor";

@Component({
  selector: "app-editor",
  template: "<div #host></div>",
})
export class EditorComponent implements AfterViewInit, OnDestroy {
  @ViewChild("host", { static: true }) host!: ElementRef<HTMLDivElement>;
  private editor: RichTextEditorInstance | null = null;

  async ngAfterViewInit() {
    this.editor = await createRichTextEditor(
      this.host.nativeElement, { height: "480px" });
  }
  ngOnDestroy() { this.editor?.destroy?.(); }
}

Plain TypeScript

No framework needed.

Pass any element and use the instance API directly — getHTMLCode, setHTMLCode, execCommand, and attachEvent are all typed.

import { createRichTextEditor } from "ts-rich-text-editor";

const host = document.getElementById("editor")!;
const editor = await createRichTextEditor(host, { height: "480px" });

editor.attachEvent("change", () => console.log(editor.getHTMLCode()));

Class facade

Prefer an object? Use TypeScriptRichTextEditor.

The class wrapper adds an html getter/setter, an on that returns an unsubscribe function, and focus / exec / destroy helpers over the same instance.

import { TypeScriptRichTextEditor } from "ts-rich-text-editor";

const editor = await TypeScriptRichTextEditor.create(host, { height: "480px" });

editor.html = "<p>Hello</p>";        // getter / setter over the HTML
const off = editor.on("change", () => console.log(editor.html));
editor.focus();
// ...later
off();            // detach the handler
editor.destroy(); // tear the editor down

Same runtime, wherever it renders.

The editor is the shipping RichTextEditor build under a typed surface, so the API is identical in every framework — pick the lifecycle hook, mount, and destroy on unmount.