A modular, extensible rich-text editor built on top of Tiptap, published as a pnpm monorepo with two packages:
| Package | NPM | Description |
|---|---|---|
@qik-editor/core |
Headless Tiptap extensions | |
@qik-editor/react-ui-shadcn |
React toolbar & bubble-menu components |
# Core extensions only (headless)
npm install @qik-editor/core
# React UI (includes core as a dependency)
npm install @qik-editor/react-ui-shadcnPeer dependencies β make sure you have React β₯ 18 and Tiptap β₯ 3 installed:
npm install react react-dom @tiptap/react @tiptap/starter-kit
import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import { CoreExtensions } from "@qik-editor/core";
import { Toolbar } from "@qik-editor/react-ui-shadcn";
export default function Editor() {
const editor = useEditor({
extensions: [StarterKit, ...CoreExtensions],
content: "<p>Hello, QikEditor! π</p>",
});
return (
<div>
<Toolbar editor={editor} />
<EditorContent editor={editor} />
</div>
);
}Provides all Tiptap extensions pre-configured and ready to use.
| Export | Description |
|---|---|
CoreExtensions |
Full array of extensions β drop into useEditor({ extensions }) |
Heading |
Custom heading with inline styles (h1βh6) |
Paragraph |
Custom paragraph with consistent line-height |
FontFamilyExtension |
Font family picker support |
LineHeightExtension |
Line-height control |
Indent |
Indent / Outdent (Tab / Shift+Tab) |
Link |
Clickable links with bubble-menu edit |
ImageExtension |
Image upload & URL insert |
TableExtension, TableRow, TableCell, TableHeader |
Resizable tables |
CodeBlockExtension |
Syntax-highlighted code blocks (lowlight) |
VideoEmbedExtension |
YouTube / Vimeo embeds |
resolveEmbedUrl(url) |
Utility β converts a share URL to an embed URL |
import { CodeBlockExtension, VideoEmbedExtension } from "@qik-editor/core";
const editor = useEditor({
extensions: [
StarterKit,
CodeBlockExtension, // syntax highlighting via lowlight
VideoEmbedExtension, // YouTube / Vimeo embeds
],
});React components for the toolbar and bubble menus, styled with Tailwind CSS + Radix UI primitives.
import { Toolbar } from "@qik-editor/react-ui-shadcn";
<Toolbar
editor={editor}
onUpload={async (file) => {
// upload file and return the public URL
const url = await uploadToS3(file);
return url;
}}
/>;The toolbar includes (left β right):
- Font family Β· Heading level Β· Line height Β· Text align Β· Indent / Outdent
- Bold Β· Italic Β· Underline Β· Strike Β· Subscript Β· Superscript Β· Code
- Text color Β· Highlight color
- Link Β· Lists (bullet / ordered / task) Β· Blockquote Β· Code Block
- Image upload Β· Table insert Β· Video embed
import {
TextBubbleMenu,
LinkBubbleMenu,
ImageBubbleMenu,
TableBubbleMenu,
} from '@qik-editor/react-ui-shadcn';
// Place these alongside <EditorContent />
<TextBubbleMenu editor={editor} />
<LinkBubbleMenu editor={editor} />
<ImageBubbleMenu editor={editor} />
<TableBubbleMenu editor={editor} />| Menu | Appears when⦠| Actions |
|---|---|---|
TextBubbleMenu |
Text is selected | Bold, Italic, Underline, Strike, Code, Link |
LinkBubbleMenu |
Cursor is inside a link | Edit URL, Open in tab, Remove link |
ImageBubbleMenu |
Image is selected | Align left/center/right, Alt text, Replace |
TableBubbleMenu |
Cursor is inside a table | Add/delete rows & columns, Toggle header, Delete table |
All toolbar buttons are exported individually if you want to build a custom toolbar:
import {
BlockquoteButton,
CodeBlockButton,
VideoButton,
ImageButton,
TableButton,
ListButtons,
IndentButtons,
TextAlignDropdown,
HeadingDropdown,
FontFamilyDropdown,
LineHeightDropdown,
TextColorPicker,
HighlightColorPicker,
LinkButton,
TextFormatButtons,
} from "@qik-editor/react-ui-shadcn";Powered by lowlight β auto-detects and highlights JavaScript, TypeScript, CSS, HTML, JSON, Python, Go, Rust, and many more.
// Toggle code block
editor.chain().focus().toggleCodeBlock().run();
// Check if active
editor.isActive("codeBlock");Supports YouTube (watch?v=, youtu.be/, shorts/) and Vimeo URLs.
editor
.chain()
.focus()
.insertVideo({ src: "https://youtu.be/dQw4w9WgXcQ" })
.run();Fully resizable via drag handles. Bubble menu controls all row/column operations.
editor
.chain()
.focus()
.insertTable({ rows: 3, cols: 3, withHeaderRow: true })
.run();// With upload callback (recommended)
<Toolbar editor={editor} onUpload={async (file) => uploadFn(file)} />;
// Or insert by URL
editor
.chain()
.focus()
.setImage({ src: "https://example.com/photo.jpg", alt: "A photo" })
.run();This is a pnpm monorepo using Turborepo.
# Install dependencies
pnpm install
# Start dev watchers (all packages + playground)
pnpm dev
# Build all packages
pnpm build
# Open the playground at http://localhost:3000
# (started automatically by `pnpm dev`).
βββ apps/
β βββ playground/ # Next.js app for testing
βββ packages/
β βββ core/ # @qik-editor/core
β βββ react-ui-shadcn/ # @qik-editor/react-ui-shadcn
βββ pnpm-workspace.yaml
βββ turbo.json
# Build
pnpm --filter @qik-editor/core build
pnpm --filter @qik-editor/react-ui-shadcn build
# Publish
cd packages/core && npm publish --access public
cd ../react-ui-shadcn && npm publish --access publicMIT Β© phonghqh