CV Hub
Автор / Разработчик · 2026

WikiNest

Wiki — это просто Git-репозиторий. Никаких серверов, баз данных и сборки.

Platforms
  • Веб
  • GitHub Pages
  • GitLab Pages
Stack
  • HTML
  • CSS
  • GitHub API
  • GitLab API
Интерфейс редактора WikiNest

Обзор

WikiNest — git-нативная вики для небольших инженерных команд, которые хотят совместную документацию без инфраструктурных затрат. Основная идея намеренно минималистична: вики — это просто набор markdown-файлов в Git-репозитории. WikiNest выступает тонким браузерным слоем редактирования поверх этого репозитория — каждая страница, каждое сохранение автоматически превращается в Git-коммит. Нет сервера. Нет базы данных. Нет npm install, нет пайплайна сборки, нет Docker-контейнера. Всё приложение — это один `index.html` и один `style.css`. Настройка занимает две минуты: форк репозитория, включение GitHub Pages или GitLab Pages — готово. Команда получает совместную вики с версионированием с первого дня.


Проблема

Инструменты для документации малых команд имеют неудобную структуру стоимости. Устоявшиеся варианты несут лишний груз: - Confluence — SaaS с ценой за пользователя, непрозрачное версионирование, vendor lock-in - Wiki.js — требует Node.js-сервер, PostgreSQL или MongoDB, постоянное обслуживание инфраструктуры - Docusaurus / MkDocs — нужен пайплайн сборки, локальное окружение, CI для деплоя - Notion — закрытая платформа, нет реальной истории изменений, экспорт — улица с односторонним движением Для команды 2–8 инженеров, которой нужно просто писать доки и фиксировать решения, ни один из них не соразмерен реальной задаче. Ключевое наблюдение: если вы уже используете Git, у вас уже есть вся инфраструктура для вики. Файлам просто нужен нормальный редактор.


Решение

WikiNest сводит задачу к минимально необходимой форме. Приложение напрямую обращается к GitHub или GitLab API из браузера. Бэкенда нет — аутентификация происходит через personal access token, хранящийся в localStorage. Чтение и запись страниц — это API-вызовы для получения содержимого файлов и коммита изменений. Из этой архитектуры следует чистое следствие: каждое изменение автоматически версионируется. Откатите любую страницу к любому предыдущему состоянию. Видно, кто что менял и когда. История вики — это история коммитов репозитория: никакого отдельного лога, никакой проприетарной системы ревизий. Компромисс намеренный: WikiNest оптимизирован под нулевые инфраструктурные затраты и нулевую нагрузку на поддержку.


Что было сделано

  • Split-view редактор — сырой markdown слева, живой рендер справа
  • Автоматическое версионирование — каждое сохранение генерирует Git-коммит с описанием
  • Офлайн-черновики — автосохранение в localStorage каждые 500мс, изменения переживают перезагрузку
  • Drag-and-drop загрузка изображений — картинки коммитятся прямо в репозиторий как бинарные блобы
  • Вики-ссылки — синтаксис "[[Название страницы]]" с автодополнением по существующим страницам
  • Полнотекстовый поиск — индекс генерируется CI при каждом пуше, поиск работает на клиенте
  • История страницы — последние 20 коммитов с просмотром изменений
  • Управление папками — создание и переименование папок с произвольными именами
  • Деплой на GitHub Pages и GitLab Pages без отдельного хостинга
  • Ноль внешних зависимостей в runtime — без npm, бандлера и CDN-скриптов

Архитектура

Приложение структурно плоское: один HTML-файл, один CSS-файл, ванильный JavaScript без фреймворка. Всё состояние хранится в двух местах: - Git-репозиторий — канонический, версионированный источник правды для всего контента - localStorage — временное состояние сессии (токен, черновики, настройки UI) Путь чтения: Браузер вызывает GitHub/GitLab REST API для получения содержимого файлов. Markdown парсится и рендерится на клиенте. Сервер не задействован. Путь записи: При сохранении приложение вычисляет base64-кодировку обновлённого файла и вызывает API обновления файла с текущим SHA. API атомарно коммитит новую версию. Конфликты обнаруживаются через SHA — если файл изменился с последнего чтения, коммит отклоняется с понятной ошибкой. Путь поиска: GitHub Actions запускает workflow при каждом пуше и генерирует плоский JSON-индекс всего контента. Браузер загружает этот индекс один раз за сессию и выполняет полнотекстовый поиск локально. Эта архитектура означает нулевую операционную стоимость — в пределах лимитов API стандартного бесплатного аккаунта GitHub, что с запасом подходит любой команде.


Системная модель

WikiNest намеренно построен как инверсия типичной архитектуры wiki-систем. Традиционные платформы документации почти всегда вводят отдельный backend-слой: сервер приложения, базу данных, систему аутентификации, поисковую инфраструктуру, отдельный deployment pipeline. WikiNest убирает этот слой полностью и рассматривает существующую Git-инфраструктуру как саму платформу. В результате системная модель выглядит так: - Git-репозиторий → каноническая база данных - GitHub/GitLab API → слой записи и персистентности - GitHub Pages / GitLab Pages → runtime-хостинг - CI pipeline → асинхронная система индексации - Браузер → runtime приложения - localStorage → временный session cache Браузер фактически работает как распределённый клиент для Git-backed document store. Это полностью меняет операционную модель. Нет жизненного цикла сервера, миграций базы данных, оркестрации runtime-инфраструктуры или отдельного слоя хранения. Репозиторий и есть система.


Почему без backend

Отсутствие backend-слоя — не ограничение проекта, а его ключевое архитектурное условие. В основе проекта лежал конкретный вопрос: "Какую часть collaborative documentation infrastructure можно заменить самим Git?" Git уже предоставляет: - Историю изменений - Модель конкурентности - Rollback - Audit trail - Контроль доступа - Репликацию - Хостинг - Review workflow - Deployment pipeline Большинство wiki-систем заново реализуют эти механики внутри собственного application stack. WikiNest вместо этого использует Git как нативный слой хранения и совместной работы с самого начала. Из этого следуют важные последствия: - Нет provisioning инфраструктуры - Нет операционной поддержки серверов - Нет сложности деплоя - Нет проприетарного data layer - Нет vendor lock-in - Нет отдельной системы синхронизации между wiki и Git Компромисс здесь тоже намеренный: архитектура prioritises transparency, portability и operational simplicity вместо enterprise-функций совместной работы.


Абстракция Git-провайдеров

Одной из важных инженерных задач было избежать жёсткой привязки к конкретному Git-провайдеру. WikiNest поддерживает одновременно GitHub и GitLab через нормализованный provider layer, абстрагирующий различия между их REST API. Внутри приложения операции: - чтения файлов - записи файлов - удаления - получения истории коммитов - проверки pipeline status - получения raw-контента преобразуются в provider-agnostic операции. GitHub и GitLab используют разные API shapes, схемы аутентификации и deployment-модели. WikiNest приводит их к общей внутренней модели, чтобы остальная часть приложения могла работать независимо от платформы. Например: - GitHub использует `PUT /contents/{path}`, тогда как GitLab разделяет create/update через `POST` и `PUT` - GitHub Actions и GitLab Pipelines возвращают разные deployment payload - GitLab использует `last_commit_id`, а GitHub — blob SHA Эти различия скрываются за тонким abstraction layer без изменения UX или пользовательского workflow.


Модель консистентности

WikiNest намеренно работает как eventually consistent система. Raw CDN endpoints у GitHub и GitLab агрессивно кешируют markdown-файлы — обычно 30–60 секунд. После сохранения новое состояние репозитория может уже существовать в Git, но ещё не быть доступным через CDN. Вместо борьбы с этим поведением приложение строится вокруг него. После сохранения: - Редактор сразу показывает локальную версию документа - Sidebar обновляется optimisticly без ожидания CI - Deploy watcher отслеживает статус последнего pipeline - `tree.json` и `search.json` перезагружаются только после успешного деплоя Это создаёт UX, который ощущается отзывчивым, оставаясь полностью статическим и backendless. Обнаружение конфликтов реализовано структурно через Git SHA. Каждая операция записи содержит SHA последней известной версии файла. Если кто-то изменил файл раньше — Git-провайдер автоматически отклоняет commit. На практике Git сам становится системой контроля конкурентности.


Архитектура поиска

Полнотекстовый поиск реализован без отдельной поисковой инфраструктуры. При каждом push CI проходит по директории `docs/` и генерирует два статических артефакта: - `tree.json` → метаданные страниц, иерархия, excerpts и timestamps - `search.json` → плоский full-text индекс markdown-контента Frontend загружает `search.json` лениво — только при первом открытии поиска, а не во время initial page load. Это сохраняет быстрый startup даже для больших wiki. Сам поиск полностью выполняется на клиенте. Архитектурно это переносит стоимость индексации в CI вместо runtime. Браузер получает заранее подготовленный индекс и выполняет мгновенный in-memory search без backend dependency. Компромисс — асинхронная индексация: поисковый индекс всегда немного отстаёт от последнего commit.


Модель безопасности

WikiNest использует намеренно лёгкую security model, рассчитанную на внутреннюю инженерную документацию, а не enterprise zero-trust environments. Для редактирования одновременно необходимы: - Write access к репозиторию - Валидный Personal Access Token - Локальный edit password Personal Access Token никогда не хранится серверно, потому что сервера просто нет. Вместо этого: - Токен хранится в localStorage - При наличии edit password токен XOR-обфусцируется перед сохранением - Расшифровка происходит только после ввода правильного пароля - Дешифрованный токен существует только в runtime memory текущей сессии Это намеренно описывается как obfuscation, а не как полноценная криптографическая защита. Цель — не enterprise-grade secret management, а снижение риска случайной утечки plaintext-токена при сохранении zero-backend архитектуры. Дополнительно проект защищает несколько browser-side attack surface: - User-controlled строки escaping перед HTML interpolation - Использование DOM API вместо inline HTML construction - Валидация путей против traversal sequence - Subresource Integrity для внешних CDN scripts Основное осознанное ограничение связано с markdown rendering. Пользовательский markdown рендерится client-side через `marked.js`, поэтому компрометация репозитория теоретически может привести к исполнению вредоносного контента. Для целевого use-case — небольших инженерных команд внутри доверенного репозитория — этот компромисс был признан приемлемым.


Операционная философия

WikiNest намеренно оптимизирован вокруг operational minimalism. Современные documentation systems часто постепенно накапливают инфраструктуру: database → auth → object storage → deployment pipeline → search service → background jobs → backups → monitoring В какой-то момент сама документационная система превращается в отдельный production-service. WikiNest намеренно движется в противоположную сторону. Вся система — это: - один HTML-файл - один CSS-файл - один репозиторий - статический хостинг - provider API - CI-генерируемые метаданные Никакого package manager, server process или контейнеров. Результат — инструмент с крайне прозрачной операционной моделью: - Каждая страница — обычный markdown-файл - Каждое изменение — обычный Git-коммит - Каждый деплой — стандартный Pages deployment - Любой failure mode inspectable через стандартный Git tooling Новый инженер может понять практически всю систему за один вечер.


Инженерные ограничения

На архитектуру проекта сильно повлияли заранее заданные ограничения: - Без framework runtime - Без build step - Без server-side execution - Без внешней базы данных - Без bundler - Без dependency graph Эти ограничения вынудили архитектуру двигаться в сторону предельной явности и простоты. Механики, которые обычно скрыты за framework abstraction, пришлось реализовывать напрямую: - optimistic UI updates - debounced rendering - split-view synchronization - provider API normalization - CI deployment tracking - markdown parsing pipeline - wiki-link autocomplete - tree rendering из flat structures - offline draft persistence Такой constraint-driven подход позволил сохранить codebase экстремально маленькой, при этом поддерживая collaborative editing, поиск, version history и deployment feedback. Финальное приложение остаётся близко к ~1000 строкам ванильного HTML/CSS/JS.


Инженерные решения

  • Без фреймворка — ванильный JS исключает вес бандла и зависимостей
  • API-first запись — использование API Git-провайдера делает версионирование структурным
  • localStorage для токена — нет серверного управления сессиями, токен не покидает браузер
  • CI-генерируемый поисковый индекс — поиск мгновенный без индексации на клиенте при загрузке
  • Однофайловая дистрибуция — всё приложение форкается и деплоится за минуты
  • Автосохранение каждые 500мс — защита данных без серверного уровня персистентности

Компромиссы

  • Нет совместного редактирования в реальном времени — конкурентные правки требуют ручного разрешения через Git
  • Авторизация через personal access token — не подходит для организаций с требованиями SSO
  • Поисковый индекс с задержкой ~1 коммит — контент индексируется после следующего CI-запуска
  • Лимиты API GitHub/GitLab — не критично для малых команд
  • Только markdown, без WYSIWYG — намеренный компромисс ради простоты и портируемости

Результат

  • Полноценная вики без серверной инфраструктуры
  • Каждое изменение — отслеживаемый и обратимый Git-коммит
  • Время настройки: менее 2 минут от форка до работающей вики
  • Работает на любом статическом хостинге с поддержкой GitHub/GitLab Pages
  • Кодовая база: ~1000 строк ванильного HTML/CSS/JS
  • MIT лицензия, готов к форку шаблонный репозиторий

Выводы

WikiNest — исследование ограничений как инструмента проектирования. Отказ от сервера, базы данных и шага сборки сделал все остальные решения очевидными: работать напрямую с API Git-провайдера, хранить состояние в localStorage, генерировать поисковый индекс в CI, дистрибутировать одним файлом. Результат — инструмент, который работает с первого дня, не стоит ничего в эксплуатации и полностью прозрачен: весь код приложения можно прочитать за пару часов. Для небольших инженерных команд эта прозрачность и отсутствие операционной нагрузки часто ценнее, чем богатство функций тяжёлых альтернатив. Это также демонстрирует обобщаемый паттерн: многие инструменты, которые считают, что им нужен бэкенд, на самом деле не нуждаются в нём — если принять правильные компромиссы и строить поверх API, которые пользователи уже используют.