Открываешь сайт — получаешь Next.js-проект на диске
Не так давно мне понадобилось восстановить интерфейс одного маркетингового сайта, исходники которого канули в Лету вместе с подрядчиком. Точнее, у заказчика оставалась только продакшен-ссылка. Раньше я бы потратил вечер на копирование вёрстки вручную, но в этот раз наткнулся на проект, который делает это за минуту. И не через LLM, что для меня оказалось неожиданностью.
Что такое ditto.site
ditto.site — open source компилятор на TypeScript, который берет публичный URL и превращает его в самодостаточный проект. По умолчанию на выходе Next.js App Router, по запросу — Vite React. Стили идут через Tailwind или обычный CSS.
Сразу уточню, что имеет в виду автор под «клонированием». Никакого git clone здесь нет: вам не нужен репозиторий сайта и его исходный код. Нужна только ссылка, доступная из браузера. Инструмент открывает страницу, записывает то, что браузер реально отрендерил, и пишет из этого новый проект.
Автор прямо называет свою систему «capture-to-code pipeline» и подчеркивает, что компилятор — не LLM-автор страниц. Одна и та же зафиксированная копия всегда дает байт-в-байт одинаковый результат на выходе. Кстати, именно детерминированность здесь продают как главную фичу, и это честнее, чем мистическая генерация нейросетью, где каждый запуск отличается.
У проекта уже 1580 звезд и 214 форков на GitHub, лицензия MIT. Проект свежий, но сообщество вокруг него формируется быстро.
Как этим пользоваться
Три пути. Самый простой — локальный CLI:
git clone https://github.com/ion-design/ditto.site.git
cd ditto.site
npm ci
npx playwright install chromium
npm run clone -- https://example.com/ --out=./output
После установки Chromium команда npm run clone открывает страницу, снимает состояние и раскладывает готовое приложение в output/<site>/app. Мне понравилась деталь: без флага --out результаты складываются в runs/<site>/<timestamp>/, а симлинк runs/<site>/latest всегда указывает на свежий клон. Скрипты можно не переписывать под новый timestamp.
Есть режимы для ленивых:
npm run clone -- https://example.com/ --serve # клонирует и сразу поднимает dev-сервер
npm run clone -- https://example.com/ --open # плюс открывает браузер
Второй путь — REST API на api.ditto.site. Заводите ключ через форму или curl с верификацией почты, экспортируете его в DITTO_API_KEY и запускаете задачу:
curl -sS -X POST "$DITTO_API_URL/v1/clones" \
-H "authorization: Bearer $DITTO_API_KEY" \
-H "content-type: application/json" \
-d '{
"url": "https://example.com/",
"options": {
"mode": "single",
"styling": "tailwind",
"framework": "next"
}
}'
В ответ приходит карта файлов, где у каждого файла свой путь, размер и SHA-256. Разворачивать в дерево на диске помогает их же CLI-распаковщик, а весь проект целиком можно скачать одним архивом через /bundle?format=tgz.
Третий путь — MCP-сервер, и это, честно говоря, самое интересное для меня. ditto.site подключается к агентам как обычный MCP-инструмент, и сервер спроектирован экономно: сначала агент получает только идентификаторы задачи и метаданные, а файлы читает по мере необходимости. Инструменты типа clone_website, list_clone_files и read_clone_files позволяют агенту самому запустить клон, подождать завершения и выборочно прочитать package.json или конкретный компонент.
Что попадает в сгенерированный проект
На выходе получается не только вёрстка. Судя по README, приложение включает:
- восстановленные страницы и модули маршрутов;
- захваченные ассеты, шрифты, иконки, манифесты и метаданные;
robots,sitemap,llms.txtи JSON-LD, если их удалось обнаружить;- небольшие рантайм-хелперы для распознанных интеракций и анимаций;
- сгенерированные
AGENTS.mdиARCHITECTURE.mdдля передачи проекта дальше.
Последний пункт я отмечу отдельно. Автор явно рассчитывает, что дальше над кодом поработает человек или ИИ-агент, и сразу кладет в проект инструкцию, какие файлы безопасно редактировать: src/app/content.ts и src/app/components/. Это редкий уровень заботы для генератора.
Как это работает внутри
Пайплайн выглядит так: URL → захват браузером → нормализованный промежуточный рендер → детерминированный вывод → генерация приложения → материализация ассетов → опциональная валидация.
Захват пишет DOM, вычисленные стили, layout-боксы, исходный CSS, шрифты, скриншоты и состояния интеракций. Репродюцируемую анимацию тоже старается зафиксировать, если она наблюдаема. А вот произвольный сторонний JavaScript, авторизация, платежи и персонализация не воспроизводятся. Это логичное ограничение: инструмент работает с тем, что видно в браузере, а не с серверной логикой.
В репозитории приличная архитектура: компилятор, Hono REST API вместе с MCP-сервером, Drizzle-схема с миграциями, воркер для очереди задач, хранилище артефактов под S3/R2. Можно поднять всё локально через docker compose с Postgres и MinIO, а можно запустить упрощенный инлайн-режим без базы одной командой. Для локального API есть и MCP-эндпоинт на localhost:8787/mcp.
Мне нравится, что в опциях есть verify и asyncVerify: сгенерированный проект можно прогнать через валидацию и получить подтверждение, что он хотя бы собирается и рендерится похоже на оригинал.
Где это пригождается
Первый сценарий очевиден: восстановление сайта, когда исходников нет. Заброшенный лендинг, потерянные исходники от подрядчика, легаси-страница, которую надо переехать в современный стек. Здесь инструмент решает задачу за минуты.
Второй сценарий — прототипирование. Клиент показывает «хочу как вот тут» и кидает ссылку. Вместо абстрактных обсуждений вы за пару минут получаете рабочий проект со структурой Next.js, и уже в нем обсуждаете отличия. Для фрилансера, который оценивает объем работ по чужому референсу, это ускоряет старт.
Третий сценарий — автоматизация через MCP. Агенту можно поручить: «склонируй этот сайт как Next.js-приложение, дождись завершения, прочитай сгенерированные файлы». Формат «только нужные файлы» экономит контекст агента, и авторы явно это продумали.
Обратная сторона и правила игры
Без оговорок не обошлось. CLI пока живет внутри репозитория и не опубликован в npm, так что npx ditto не сработает — надо клонировать репозиторий целиком. Это не то, что поставишь в CI одной строкой, но авторы предупреждают об этом честно.
Дальше, этика. README постоянно напоминает: используйте инструмент только там, где у вас есть право копировать и трансформировать контент. Фишинг, подделка брендов, обход авторизации и массовый захват чужих сайтов запрещены явно, у проекта есть отдельный документ RESPONSIBLE_USE.md. Звучит правильно: технология сама по себе нейтральна, но применять ее стоит к своим проектам или с разрешения владельцев.
И еще одно. По-русски и по-английски слово «клонирование» звучит дерзко, а по факту это реконструкция видимой части страницы. Не ждите, что инструмент вытащит серверный код, базу данных или бизнес-логику, он честно пишет об этом в README.
Кому попробовать
Если вы верстаете лендинги, переносите сайты в новый стек или хотите дать ИИ-агенту аккуратный инструмент для работы с веб-интерфейсами, посмотрите на ditto.site. Начните с локального CLI, он не требует ключей: npm run clone -- https://example.com/ --serve, и через пару минут у вас крутится дев-сервер на восстановленном проекте. А если захочется вкорячить это в свой пайплайн, REST API и MCP-сервер уже в комплекте. Для дизайнера или техлида, который часто получает «сделай как тут», инструмент выглядит как честный ответ на очень частую боль.
