Разработка онлайн-редактора документов для совместной работы

Разработка онлайн-редактора документов для совместной работы

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

Это лишь некоторые из технических типов сайтов, с которыми мы работаем, и каждый из них может иметь свои специфические особенности и функциональность, а также быть адаптированным под конкретные потребности и цели клиента

Услуги, которые мы предлагаем
Показано 1 из 1Все 2062 услуг
Разработка онлайн-редактора документов для совместной работы
Сложный
от 2 недель до 3 месяцев

Наши компетенции:

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1414
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1285
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    980
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1240
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    982
  • image_bitrix-bitrix-24-1c_fixper_448_0.webp
    Разработка веб-сайта для компании ФИКСПЕР
    994

Разработка онлайн-редактора документов для совместной работы

Совместное редактирование документов в реальном времени — технически сложная задача. Мы столкнулись с ней, когда клиент попросил заменить Google Docs для внутреннего документооборота: требовались форматирование, комментарии, история версий и одновременная работа нескольких авторов. На основе нашего опыта мы собрали типовую архитектуру, которая сокращает время разработки до 6-14 недель. Ключевая проблема — обеспечить бесшовную синхронизацию при редактировании десятков пользователей одновременно. Большинство готовых решений либо не дают контроля над данными, либо избыточны. Мы строим редакторы на основе CRDT и Y.js — это современный стандарт коллаборации, который в 3 раза быстрее старых OT-протоколов.

Почему готовые решения не подходят?

Google Docs не даёт полного контроля над данными и интерфейсом. Notion и Confluence — слишком громоздки для простого текстового редактора. А разработка с нуля без правильного стека — путь к бесконечным багам синхронизации. Например, один из наших клиентов пытался использовать операционные преобразования (OT) и столкнулся с неразрешимыми конфликтами при 20+ одновременных авторах. Переход на CRDT решил проблему: синхронизация стала детерминированной, а скорость обновлений выросла в 2-3 раза.

Как мы делаем это: стек и архитектура

Выбор движка редактора

Три основных варианта с разными trade-off:

Движок Гибкость Порог входа Готовые расширения Примеры
ProseMirror Максимальная Высокий Минимум (схема своя) Notion, Confluence
Tiptap Высокая Средний Богатый (collaboration, tables, mentions) наши проекты
Lexical (Meta) Средняя Низкий Развивающийся (меньше чем Tiptap) Facebook, WhatsApp

Для большинства задач выбираем Tiptap: он построен на ProseMirror, но даёт удобный extension API и встроенную поддержку Y.js для коллаборации:

import { useEditor, EditorContent } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import Collaboration from '@tiptap/extension-collaboration'; import CollaborationCursor from '@tiptap/extension-collaboration-cursor'; import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; const ydoc = new Y.Doc(); const provider = new WebsocketProvider('wss://collab.example.com', documentId, ydoc); const editor = useEditor({ extensions: [ StarterKit.configure({ history: false }), // отключаем — Y.js сам управляет history Collaboration.configure({ document: ydoc }), CollaborationCursor.configure({ provider, user: { name: currentUser.name, color: currentUser.color }, }), ], }); 

CRDT через Y.js

Операционные преобразования (OT) — старый подход (Google Docs). CRDT (Conflict-free Replicated Data Types) — современная альтернатива. CRDT гарантирует, что все реплики документа сойдутся к одному состоянию без центрального сервера. Y.js — самая зрелая CRDT-библиотека для JavaScript. Принцип: каждое изменение — это операция, которая применяется в любом порядке и даёт одинаковый результат. Нет центрального сервера, который должен сериализовать операции.

import * as Y from 'yjs'; const doc = new Y.Doc(); const ytext = doc.getText('content'); // Два пользователя редактируют оффлайн const doc1 = new Y.Doc(); const doc2 = new Y.Doc(); const text1 = doc1.getText('content'); const text2 = doc2.getText('content'); // Оба начинают с одного состояния const initialState = Y.encodeStateAsUpdate(doc); Y.applyUpdate(doc1, initialState); Y.applyUpdate(doc2, initialState); // Пользователь 1 вставляет "Hello" text1.insert(0, 'Hello'); // Пользователь 2 вставляет "World" — оффлайн text2.insert(0, 'World'); // Синхронизация: применяем update от doc1 к doc2 и наоборот Y.applyUpdate(doc2, Y.encodeStateAsUpdate(doc1)); Y.applyUpdate(doc1, Y.encodeStateAsUpdate(doc2)); // Оба документа сходятся к одному состоянию (порядок зависит от алгоритма) console.log(text1.toString()); // "HelloWorld" или "WorldHello" — deterministically console.log(text2.toString()); // то же самое 

WebSocket-сервер для Y.js

y-websocket — референсная реализация на Node.js. Для production рекомендуем hocuspocus (официальный бэкенд Tiptap) или y-redis для персистенции. Ниже пример с Redis:

import { WebSocketServer } from 'ws'; import { setupWSConnection } from 'y-websocket/bin/utils.js'; import { createClient } from 'redis'; const wss = new WebSocketServer({ port: 1234 }); const redis = createClient({ url: process.env.REDIS_URL }); await redis.connect(); const persistence = { provider: 'redis', bindState: async (docName, ydoc) => { const savedState = await redis.get(`ydoc:${docName}`); if (savedState) { Y.applyUpdate(ydoc, Buffer.from(savedState, 'base64')); } ydoc.on('update', async (update) => { const state = Y.encodeStateAsUpdate(ydoc); await redis.set( `ydoc:${docName}`, Buffer.from(state).toString('base64'), { EX: 86400 * 30 } // 30 дней ); }); }, writeState: async () => {}, }; wss.on('connection', (ws, req) => { const docName = new URL(req.url, 'ws://x').pathname.slice(1); setupWSConnection(ws, req, { docName, persistence }); }); 

Структура базы данных

CREATE TABLE documents ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title TEXT NOT NULL DEFAULT 'Untitled', owner_id BIGINT REFERENCES users(id), ydoc_state BYTEA, -- сериализованное состояние Y.Doc snapshot_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE document_collaborators ( document_id UUID REFERENCES documents(id) ON DELETE CASCADE, user_id BIGINT REFERENCES users(id), role TEXT CHECK (role IN ('viewer', 'commenter', 'editor', 'owner')), invited_at TIMESTAMPTZ DEFAULT NOW(), PRIMARY KEY (document_id, user_id) ); -- История версий (снапшоты) CREATE TABLE document_snapshots ( id BIGSERIAL PRIMARY KEY, document_id UUID REFERENCES documents(id) ON DELETE CASCADE, ydoc_state BYTEA NOT NULL, created_by BIGINT REFERENCES users(id), label TEXT, -- "перед публикацией", "версия для клиента" created_at TIMESTAMPTZ DEFAULT NOW() ); 

Комментарии и трекинг изменений

Комментарии реализуются через Mark extension в Tiptap/ProseMirror. Каждый комментарий имеет уникальный ID, статус (открыт/закрыт) и привязывается к выделению. Хранятся в отдельной таблице и синхронизируются через Y.js.

Экспорт документов: DOCX и PDF

Конвертация ProseMirror JSON → HTML → DOCX/PDF. Для DOCX используем pandoc (на бэкенде) или нативный npm-пакет docx. PDF — через Headless Chrome (Puppeteer) или pdfkit. Выбор зависит от требований к оформлению.

Что такое CRDT и почему это лучше? (H2)

CRDT (Conflict-free Replicated Data Types) — математическая модель, обеспечивающая согласованность данных без блокировок. В отличие от операционных преобразований (OT), CRDT не требует центрального сервера и устойчив к задержкам сети. Y.js использует список с метками (version vectors), что позволяет автоматически разрешать конфликты. Посмотрите на наглядное сравнение:

Характеристика CRDT (Y.js) OT (ShareJS)
Зависимость от сервера Нет (peer-to-peer возможна) Да (сервер переупорядочивает операции)
Поведение при офлайн Любое число реплик Ограниченная поддержка
Производительность при большом числе пользователей Устойчив на сотнях участников Требует сериализации (узкое место)
Сложность реализации Средняя (библиотека Y.js) Высокая (алгоритм изменения порядка)

Как мы строим процесс разработки? (H2)

  1. Аудит требований (1-2 недели) — анализируем сценарии использования, число пользователей, формат документов.
  2. Проектирование архитектуры (1 неделя) — выбор стека, схемы БД, протокола синхронизации.
  3. Реализация ядра редактора (4-6 недель) — интеграция Tiptap с Y.js, базовые расширения.
  4. Добавление коллаборации (4-6 недель) — поддержка множества курсоров, офлайн-редактирование, историю версий.
  5. Экспорт и система прав (2-3 недели) — конвертеры, роли пользователей, публичные ссылки.
  6. Тестирование и деплой (2-3 недели) — нагрузочное тестирование симуляциями, CI/CD.

Каждый этап включает демо-версию для вашей команды. Ваши инженеры получают доступ к репозиторию с первого дня.

Какие риски при разработке редактора? (H2)

Основные сложности:

  • Hydration mismatch при SSR: если используете Next.js, убедитесь, что Y.js документ не переопределяет клиентское состояние.
  • Масштабирование WebSocket: для тысяч документов потребуется кластеризация (например, через Redis Pub/Sub).
  • Безопасность: валидация входящих операций на бэкенде, чтобы избежать XSS через контент.

Что входит в работу

По завершении проекта вы получаете:

  • Исходный код репозитория (Git)
  • Документацию по API и архитектуре
  • Инструкцию по развёртыванию (Docker, CI/CD)
  • Доступ к админ-панели управления пользователями
  • Обучение команды (2-3 часа онлайн)
  • Гарантию на код — 6 месяцев бесплатной поддержки

Сроки и бюджет

Ориентировочные сроки:

  • Базовая версия (один редактор) — 6-8 недель
  • Добавление совместного редактирования — 4-6 недель
  • Полноценная система прав и история версий — 3-4 недели

Стоимость рассчитывается индивидуально после анализа ваших требований. Инвестиции окупаются за счёт ускорения документооборота. Свяжитесь с нами для бесплатной консультации и оценки проекта. Получите демо-версию для вашей команды.

Гарантия качества: наши инженеры имеют 5+ лет опыта в разработке редакторов, мы реализовали 50+ проектов для разных отраслей.