Rich Text Editing Done Right
Rahul Bhatt
Co-founder, TasksFlow
The text editor is the most frequently touched surface in any project management tool. Whether writing a feature specification, listing QA steps, or commenting on a bug, you interact with text. We chose Tiptap — a headless wrapper around ProseMirror, which forms the robust foundation of tools like Notion and Atlassian.
Why a Headless Editor?
Many frameworks ship with pre-built editors that bundle their own styling and UI controls. While fast to integrate, they make custom design systems a nightmare. A headless editor gives us complete control over the DOM nodes, allowing us to bind custom Tailwind UI controls while letting ProseMirror handle the complex document schema and selection states.
Building Custom Mentions with Autocomplete
One of our most requested features was @mention support. Users expect suggestions to appear instantly as they type. To achieve this, we wrote a custom ProseMirror suggestion extension that hooks into our workspace member list. Here is a simplified version of our extension setup:
import { Extension } from '@tiptap/core';
import Suggestion from '@tiptap/suggestion';
export const MentionSuggestion = Extension.create({
name: 'mentionSuggestion',
addProseMirrorPlugins() {
return [
Suggestion({
char: '@',
command: ({ editor, range, props }) => {
editor
.chain()
.focus()
.insertContentAt(range, [
{
type: 'mention',
attrs: props,
},
{
type: 'text',
text: ' ',
},
])
.run();
},
}),
];
},
});
The Technical Challenges
While ProseMirror is powerful, integrating it in a high-concurrency real-time environment posed several technical challenges:
- Mobile Viewports: Ensuring suggestion popovers align correctly and don't get cut off by keyboard overlays on iOS and Android.
- Image Upload Pipelines: Supporting copy-paste and drag-and-drop of images. We intercept the drop event, upload the asset asynchronously to our Cloudflare R2 bucket, and render a loading state inline before replacing it with the final URL.
- Performance: Large descriptions can lag during fast typing. We optimized this by selectively mounting editor instances and deferring initialization for collapsed comments.
Why Not Notion-Style Blocks?
Block-based editors are incredible for document layout, but they feel heavy-handed and slower for quick comments and brief descriptions. Standard inline rich text with markdown shortcuts (like typing # for a header or - for a list) gives users 90% of the editing power with a fraction of the interaction complexity.
Subscribe to our engineering log
Technical articles on WebSockets, ProseMirror plugins, database optimizations, and design philosophy. Delivered twice a month.