# MDN browser-compat-data → SQLite за один вечер: Claude пишет скрипт, GPT-5.5 деплоит
Каноническая страница: https://plainews.ru/posts/mdn-browser-compat-data-sqlite-github-actions
Опубликовано: 2026-06-25T07:01:12.148Z

Как превратить 66 МБ данных о совместимости браузеров в SQLite-базу, раздать через GitHub CDN с CORS и исследовать в Datasette Lite — пошаговый разбор.
Данные о совместимости браузеров из репозитория mdn/browser-compat-data — это тысячи JSON-файлов про поддержку Web API, CSS-свойств и JS-фич во всех актуальных браузерах. Работать с ними напрямую неудобно: нужно либо парсить JSON руками, либо тащить тяжёлый npm-пакет. Саймон Уиллисон решил иначе — конвертировал всё в SQLite и раздал через GitHub с открытыми CORS-заголовками, чтобы база открывалась прямо в браузере.

Ниже — как повторить этот подход для любого похожего датасета: AI-ассистент пишет конвертер, GitHub Actions собирает базу и пушит в отдельную ветку, Datasette Lite позволяет исследовать результат без сервера.

## Почему обычный GitHub Releases не подошёл

Первый инстинкт — залить готовую базу через GitHub Releases. Не сработало: файлы из Releases раздаются без заголовка Access-Control-Allow-Origin, то есть CORS закрыт. Datasette Lite (и любой другой браузерный клиент) не сможет загрузить такой файл напрямую.

Файлы из обычных веток репозитория — другое дело. GitHub CDN отдаёт их с открытыми CORS-заголовками. Поэтому схема такая: Actions собирает базу и **force-push'ит её в отдельную orphan-ветку** db. Orphan-ветка не имеет общей истории с main, не засоряет граф коммитов и при каждом пересборке просто перезаписывается.

## Шаг 1. Конвертируем JSON в SQLite с помощью sqlite-utils

Уиллисон использовал Claude Code (Opus 4.8, веб-версия) для генерации скрипта конвертации. Инструмент sqlite-utils — питоновская утилита, которая умеет вставлять словари прямо в таблицы SQLite, создавая схему на лету.

Структура mdn/browser-compat-data такова: каждый JSON-файл содержит вложенные объекты с ключом __compat, внутри которого — поле support со статусами по каждому браузеру. Скрипт обходит дерево рекурсивно и вставляет каждый __compat-объект как строку таблицы.

```python import json import pathlib import sqlite_utils

db = sqlite_utils.Database("browser-compat.db")

def walk_compat(data, path=""):     for key, value in data.items():         current_path = f"{path}.{key}" if path else key         if isinstance(value, dict):             if "__compat" in value:                 row = {"feature": current_path}                 row.update(value["__compat"])                 db["compat"].insert(row, alter=True)             walk_compat(value, current_path)

bcd_root = pathlib.Path("browser-compat-data") for json_file in bcd_root.rglob("*.json"):     with open(json_file) as f:         walk_compat(json.load(f)) ```

Итоговый размер базы — около 66 МБ. Поле support хранится как JSON-строка; при необходимости его можно развернуть в отдельные таблицы, но для базового поиска хватает и так.

## Шаг 2. GitHub Actions собирает базу автоматически

Скрипт для Actions генерировал Codex Desktop (GPT-5.5). Workflow клонирует mdn/browser-compat-data, запускает конвертер, а затем force-push'ит результат в ветку db.

```yaml name: Build SQLite DB

on:   schedule:

workflow_dispatch:

- cron: "0 3 * * 1"   # каждый понедельник в 3:00 UTC

jobs:   build:     runs-on: ubuntu-latest     steps:

- uses: actions/checkout@v4

run: git clone --depth 1 https://github.com/mdn/browser-compat-data

- name: Clone browser-compat-data

uses: actions/setup-python@v5         with:           python-version: "3.12"

- name: Set up Python

run: pip install sqlite-utils

- name: Install dependencies

run: python convert.py

- name: Run conversion script

run: |           git config user.email "actions@github.com"           git config user.name "GitHub Actions"           git checkout --orphan db-tmp           git rm -rf . --quiet           mv browser-compat.db .           git add browser-compat.db           git commit -m "Rebuild $(date -u +%Y-%m-%d)"           git push origin HEAD:db --force         env:           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} ```

- name: Push DB to orphan branch

Ключевой момент: git checkout --orphan db-tmp создаёт ветку без истории, git rm -rf . очищает рабочую директорию, и в коммит попадает только сам файл базы. Force-push перезаписывает ветку db при каждом запуске — история не накапливается, место не растёт.

## Шаг 3. Исследуем базу в Datasette Lite

После того как база лежит в ветке db, прямая ссылка на файл выглядит так:

`` https://raw.githubusercontent.com/simonw/browser-compat-db/db/browser-compat.db ``

Datasette Lite — это Datasette, скомпилированный в WebAssembly и работающий целиком в браузере. Чтобы открыть базу, достаточно передать URL параметром:

`` https://lite.datasette.io/?url=https://raw.githubusercontent.com/simonw/browser-compat-db/db/browser-compat.db ``

Браузер скачивает 66 МБ, WebAssembly поднимает SQLite-движок, и можно писать SQL прямо в интерфейсе — без сервера, без установки, без аккаунта.

## Где это ломается

**GITHUB_TOKEN и права на push.** По умолчанию токен в Actions имеет право только на чтение. Нужно явно выставить permissions: contents: write в секции jobs или в настройках репозитория (Settings → Actions → General → Workflow permissions).

**Размер файла.** GitHub не принимает файлы больше 100 МБ через обычный push. Если датасет вырастет, придётся использовать Git LFS или разбивать базу. 66 МБ сейчас укладываются с запасом, но BCD активно пополняется.

**Вложенные JSON в колонках.** sqlite-utils с флагом alter=True создаёт колонку support как TEXT. Если нужна фильтрация по конкретному браузеру, придётся либо развернуть JSON в отдельные таблицы при конвертации, либо использовать SQLite-функцию json_extract() в запросах.

**Кэш GitHub CDN.** Raw-файлы кэшируются на несколько минут. После force-push новая версия базы появится не мгновенно — обычно задержка 5–10 минут.

## Что попробовать дальше

Готовая база Уиллисона доступна в репозитории simonw/browser-compat-db — можно сразу открыть в Datasette Lite и поиграть с SQL-запросами, не разворачивая ничего локально. Тот же подход работает для любого датасета в формате JSON или CSV: берёте sqlite-utils, просите AI написать конвертер, добавляете Actions-воркфлоу с orphan-веткой — и получаете бесплатный хостинг с CORS и браузерным SQL-интерфейсом.

## Источники

- Simon Willison: simonw/browser-compat-db
