LikeC4: архитектура как код — от DSL до интерактивных диаграмм

Как описывать архитектуру системы кодом с помощью LikeC4: DSL для C4-модели, автоматическая генерация диаграмм, версионирование в Git, встраивание в документацию и сравнение с Mermaid, PlantUML и Structurizr

Архитектурные диаграммы живут отдельно от кода и быстро устаревают. Кто-то рисует в Draw.io, кто-то в Miro, кто-то в PowerPoint. Через месяц после изменения системы диаграмма уже не отражает реальность, а пересобирать её вручную никто не хочет.

LikeC4 предлагает другой подход: описать архитектуру кодом на специальном DSL, хранить описание в Git рядом с исходниками и автоматически получать интерактивные диаграммы. Изменилась система — изменил код — диаграмма обновилась.

Архитектура как код: из DSL одна модель порождает несколько согласованных C4-представлений

В статье

Что такое LikeC4 и зачем он нужен

LikeC4 — open-source инструмент (MIT) для описания архитектуры системы как кода. Три ключевых свойства:

  • DSL — чистый, читаемый язык для описания компонентов, связей и представлений
  • Автоматическая визуализация — из кода генерируются интерактивные диаграммы с drill-down
  • Git-first — описание живёт в репозитории, изменения отслеживаются через обычные PR

Рабочий цикл: написал .likec4 → увидел диаграмму в IDE (VS Code extension) → закоммитил → диаграмма в документации обновилась.

Быстрый старт за 5 минут

Минимум, чтобы пощупать (сначала создайте хотя бы один .c4-файл — пример модели в разделе про DSL ниже):

npm i -D likec4
# создайте model.c4 с примером из раздела ниже
npx likec4 dev            # дев-сервер с hot-reload — диаграммы в браузере
npx likec4 validate       # проверить синтаксис и дрейф раскладки
npx likec4 build -o dist  # собрать статический сайт с интерактивными диаграммами

Раскладывать файлы удобно рядом с кодом — например:

docs/architecture/
  model.c4        # элементы и связи
  views.c4        # представления
package.json      # likec4 в devDependencies

C4-модель за 2 минуты

LikeC4 построен вокруг C4-модели Саймона Брауна — подхода к описанию архитектуры на четырёх уровнях абстракции:

  1. Context — система в окружении: пользователи и внешние системы
  2. Container — из чего состоит система: сервисы, БД, очереди, frontend
  3. Component — внутренности контейнера: модули, пакеты, слои
  4. Code — уровень классов и функций (обычно не описывается вручную)

Суть: начинаешь с самой общей картины и погружаешься в детали только там, где нужно. Каждый уровень отвечает на свой вопрос и предназначен для своей аудитории.

DSL: как описывается архитектура

Описание состоит из трёх частей: specification (какие бывают виды элементов), model (сами элементы и связи) и views (какие диаграммы из этого построить). Вот компактный пример на основе khorost.tech:

specification {
  element actor
  element system
  element container
}

model {
  reader = actor 'Читатель'

  khorost = system 'Khorost.tech' {
    angie = container 'Angie' 'reverse proxy + раздача статики'
    api   = container 'API' 'Go-сервис: бот, OAuth, оценки'
    db    = container 'PostgreSQL'
    s3    = container 'S3 / MinIO' 'статика и медиа'

    reader -> angie 'читает сайт (HTTPS)'
    angie  -> s3    'отдаёт статику'
    angie  -> api   'проксирует /api'
    api    -> db    'читает/пишет'
  }
}

views {
  view index {
    include *
  }
  view of khorost {
    include *
    autoLayout TopBottom
  }
}

Связи описываются стрелками a -> b 'подпись', вложенность (container внутри system) задаёт уровни. VS Code extension показывает диаграмму прямо при редактировании — правишь текст, картинка обновляется.

Визуализация и уровни детализации

view — это проекция модели: одна модель, много диаграмм под разные задачи и аудитории. view index { include * } показывает систему в окружении (context), а view of khorost раскрывает её внутренности (containers). Из примера выше получается примерно такая container-диаграмма:

flowchart TB reader["Читатель"] -->|HTTPS| angie["Angie
reverse proxy + статика"] angie -->|отдаёт статику| s3[("S3 / MinIO")] angie -->|/api| api["API (Go)"] api -->|читает/пишет| db[("PostgreSQL")]

flowchart TB
    reader["Читатель"] -->|HTTPS| angie["Angie
reverse proxy + статика"] angie -->|отдаёт статику| s3[("S3 / MinIO")] angie -->|/api| api["API (Go)"] api -->|читает/пишет| db[("PostgreSQL")]
Container-представление модели (иллюстрация; LikeC4 рендерит её из DSL автоматически)

Ключевое преимущество перед статичной картинкой — drill-down: если у элемента есть вложенность и заданы соответствующие view, он кликабелен, и по клику вы проваливаетесь с уровня containers на уровень components. Важно: это не магия — навигация работает там, где вы описали components и сделали их view; пустой контейнер без вложенности проваливаться некуда. Содержимое каждого view настраивается через include/exclude (можно по тегам), а раскладку LikeC4 берёт на себя (autoLayout) — двигать стрелки мышкой не нужно. Одни и те же элементы переиспользуются во многих view, поэтому при изменении модели все диаграммы остаются согласованными — нельзя поправить одну и забыть про другую.

Интеграция, валидация и CI

LikeC4 — не только редактор, у него есть CLI и несколько способов отдать диаграммы наружу:

  • Статический сайтlikec4 build -o dist генерирует самодостаточный сайт с интерактивными диаграммами (drill-down работает в браузере).
  • Картинкиlikec4 export png / likec4 export jpg для README, wiki, статьи; есть и export json (модель целиком) и export drawio.
  • Диаграмма-как-кодlikec4 gen mermaid / dot / d2 / plantuml, если нужно отдать в другой рендерер.
  • Встраивание в приложение — генерация React-компонентов (likec4 gen react) и Web Components (<likec4-view>) для вставки в свой фронтенд/документацию.

Для статического генератора вроде Hugo (где этот сайт и живёт, а основные диаграммы — на Mermaid) практичнее всего: likec4 export png для статичной картинки или likec4 build для отдельного интерактивного сайта со ссылкой на него. (Прямого export svg в CLI нет — если нужен векторный диаграмма-формат, идите через likec4 gen mermaid/d2 и рендерите им.)

Валидация и CI — главный аргумент «architecture as code». Модель проверяется автоматически:

npx likec4 validate         # синтаксис + дрейф раскладки; ненулевой код при ошибке
npx likec4 format --check   # единый стиль .c4-файлов, без правок на месте
- run: npm ci
- run: npx likec4 validate
- run: npx likec4 build -o dist   # можно опубликовать в Pages

Что ревьюить в PR (модель меняется как код): новые элементы и связи, теги, точность названий и описаний — и, главное, не смешались ли уровни C4 (контейнер не оказался среди систем, компонент — на уровне контейнеров).

И ещё плюс «текстом»: LikeC4-модель — хороший машиночитаемый контекст для AI-ассистентов, потому что архитектура хранится как текст рядом с кодом (перекликается с паттернами работы с AI).

Сравнение: Mermaid, PlantUML, Structurizr, LikeC4

Параметр Mermaid PlantUML Structurizr LikeC4
Формат Markdown-like Текст DSL + JSON DSL
C4 Через нотацию (C4-диаграммы), без единой модели Через C4-PlantUML, без единой модели Да, модель Да, модель
Уровни детализации Нет Нет Да Да
Drill-down Нет Нет Ограничен Да
Git-friendly Да Да Да Да
IDE support Ограничен Плагины Web VS Code
Встраивание JS Сервер Web app React, WC, Vite
Лицензия MIT GPL Freemium MIT

Оговорка про «Drill-down: Ограничен» у Structurizr: это не про слабость инструмента — у Structurizr тоже модель и несколько уровней. Просто интерактивная навигация там завязана на его собственный UI/экспорт, а не на картинку, которую вы вставили в свою документацию.

Когда LikeC4 уместен, а где больно

LikeC4 окупается, когда:

  • архитектура живёт и меняется, а диаграммы должны оставаться актуальными;
  • над системой работает несколько человек/команд, и важно единое, согласованное представление;
  • хочется ревьюить изменения архитектуры через PR, как код, и хранить историю в Git;
  • нужны разные срезы одной системы (context для менеджеров, containers для команды) без дублирования.

Избыточен, когда:

  • нужна разовая картинка к презентации или обсуждению — в Miro/Excalidraw это быстрее и без изучения DSL;
  • проект маленький и стабильный — одна диаграмма в Mermaid рядом со статьёй закрывает задачу;
  • никто не готов поддерживать модель: как и любой «as-code», LikeC4 ценен ровно настолько, насколько его обновляют.

Где больно (честно):

  • DSL нужно поддерживать — это код, со своим синтаксисом и ревью; без процесса модель устаревает так же, как ручная картинка.
  • autoLayout на больших графах даёт автоматическую, но не всегда красивую раскладку — крупные view бывают шумными, приходится дробить их на более узкие.
  • Не вся аудитория любит читать DSL — менеджеру проще картинку; текст хорош для тех, кто работает с архитектурой как с кодом.
  • Для разовых обсуждений Miro/Excalidraw всё равно быстрее — LikeC4 окупается на долгом сопровождении, а не на наброске «на пять минут».

Главный компромисс — порог входа и поддержка против актуальности. Miro выигрывает на старте (ноль обучения), но диаграмма расходится с реальностью через месяц. LikeC4 требует выучить DSL и встроить экспорт в пайплайн, зато архитектура перестаёт врать — потому что меняется вместе с кодом и проходит ревью. Для растущей системы это выгодная сделка; для разового наброска — нет.

Документация и первоисточники

Обсуждение в Telegram

Присоединиться →

Комментарии