Про библиотеки обычно говорят в терминах «популярная» и «умирающая», опираясь на впечатление от ленты. Мы взяли реестры пакетов и посчитали, что за последние два месяца действительно набрало ход, а что пошло вниз.
Данные: npm и PyPI, недельные загрузки пакетов; окно 6 июля — 30 августа; измерено 6 сентября. Сравниваются половины окна, а не соседние недели.
Как считалось
Окно — восемь полных недель. Внутри него мы сравниваем среднюю неделю второй половины со средней неделей первой. Соседние недели не сравниваются: один релиз, одни каникулы или одна смена расписания сборок переворачивают знак.
Загрузка пакета — это не пользователь. Это в основном машины: сборки в непрерывной интеграции, образы контейнеров, зеркала, автоматические обновления. Поэтому величина загрузок ничего не говорит о числе людей, но динамика говорит о другом и вполне полезном: меняется ли то, что команды кладут в свои сборки.
Из этого следует важное ограничение. Пакет, который переехал внутрь другого пакета, «падает», не теряя ни одного пользователя. Пакет, который начали кешировать во внутреннем зеркале, тоже падает. Мы не можем отличить эти случаи от настоящего отказа, и там, где это существенно, мы говорим об этом прямо.
Тупик: судить по звёздам и по упоминаниям
Первое, что пробуют, — посмотреть на звёзды в репозитории и на то, как часто инструмент упоминают. Не помогает по двум причинам.
Звёзды — накопительная величина: они почти никогда не уменьшаются, поэтому проект, которым перестали пользоваться, выглядит по ним ровно так же, как растущий. А упоминания измеряют внимание, и внимание системно смещено в сторону нового: инструмент, который тихо работает у половины команд, обсуждать нечего.
Загрузки этого недостатка лишены: они падают, когда пакет перестают ставить, и делают это без задержки на смену настроения.
Что растёт
Отчётливее всего растёт инструментальный слой — то, что запускается на каждой сборке. Быстрый линтер прибавил 35,6%, альтернативный набор инструментов для того же — 15,4%, транспилятор — 12,5%, сборщик — 13,3%, запускалка тестов — 12,4%, монорепо-оркестратор — 12,7%. Отдельно и сильно растут браузерные тесты: 21,1%.
Это цельная картина, а не набор случайных строк. Команды меняют не архитектуру, а обслуживающий слой: то, что выполняется десятки раз в день и где выигрыш заметен сразу.
Второй растущий блок — прикладной слой вокруг языковых моделей, но растёт в нём не то, что обсуждают. Каркас для мультиагентных сценариев прибавил 119,7% — рост от маленькой базы, и это скорее эксперименты, чем эксплуатация. Клиентские библиотеки поставщиков моделей прибавили 9,0% и 8,0%, инструментальный слой для обмена с моделями — 17,9%, пакеты вокруг протокола обмена — 8,7% и 3,7%.
Третий блок — обработка данных в процессе, без отдельного кластера: встраиваемый аналитический движок прибавил 15,2%, слой абстракции над движками — 23,3%.
Третий блок роста — фронтенд, но не там, где обычно смотрят. Крупные каркасы приложений прибавили немного: 5,3% и 4,2%. Заметно быстрее растут вещи вокруг них: типобезопасный слой описания данных — 9,4%, лёгкий серверный каркас — 8,9%, слой доступа к базе — 19,7%, и совсем небольшой по объёму, но растущий подход с разметкой вместо скриптов — 17,7%. Это тоже про обвязку, а не про смену основы.
Что сдувается
Здесь самое интересное, потому что падения оказались концентрированными.
Сильнее всего теряют высокоуровневые каркасы для приложений на языковых моделях: −20,5% у крупнейшего из них, −7,3% у его же надстройки для графов, −5,1% у соседнего каркаса, −23,2% у экспериментального. Одновременно падают отдельные векторные хранилища: −9,5% и −18,6%.
Складывать эти строки в вывод «интерес к моделям падает» нельзя — клиентские библиотеки поставщиков в том же окне растут. Картина другая: слой между приложением и моделью становится тоньше. Команды уходят от универсальных каркасов к прямым вызовам и к протокольному обмену, а векторный поиск чаще берут там, где уже лежат данные, чем ставят отдельным хранилищем.
Второе заметное падение — оркестратор трансформаций данных: −26,5%, рядом −3,2% у его конкурента. Одновременно растёт встраиваемый движок. Это то же самое движение, что и в первом случае: инструмент, который управлял конвейером, вытесняется движком, который выполняет работу прямо в процессе.
Как этим пользоваться, не обманывая себя
Первое правило: смотреть на группы, а не на строки. Одна выросшая библиотека — это новость про библиотеку. Пять выросших, делающих похожую работу, — это сигнал о смене привычки, и только он чего-то стоит при выборе.
Второе: сопоставлять рост с падением в той же нише. Прибавка у встраиваемого движка и убыль у оркестратора конвейеров вместе значат больше, чем каждая по отдельности: видно не просто рост, а замещение.
Третье: отделять эксперименты от эксплуатации по масштабу базы. Трёхзначный рост почти всегда означает маленькую базу и любопытство, а не внедрение. Устойчивый двузначный рост у пакета с миллионами загрузок — наоборот, признак того, что переезд идёт в реальных сборках.
Четвёртое: не принимать решение по одному окну. Наш замер показывает направление за два месяца. Для инструмента, который вы возьмёте на несколько лет, это слишком короткая память — но достаточная, чтобы заметить, что привычный выбор перестал быть общим.
Где мы сами себе не верим
Один пакет в нашей таблице встречается дважды — в двух реестрах, с разным знаком: в одном почти без изменений, в другом −20,5%. Это хорошее напоминание, что мы меряем не «интерес к технологии», а поведение конкретной экосистемы. Переносить вывод из одного реестра в другой нельзя.
Отдельно про пакет для инференса, который показал −21,5%. У таких вещей высока вероятность внутренних зеркал и перехода на образы контейнеров вместо установки из реестра. Мы оставили строку в таблице, но не строим на ней выводов.
И общее: два месяца — короткое окно. Оно надёжно ловит направление у пакетов с большими объёмами и совершенно ненадёжно — у маленьких. Трёхзначный рост в верхней строке означает лишь, что там сотни тысяч загрузок против миллионов у соседей.
Позиция редакции
Мы считаем, что в этих числах видно одно движение, а не десять: слой, который управлял чем-то со стороны, уступает слою, который делает работу внутри процесса. Это верно и для трансформаций данных, и для обвязки вокруг моделей, и, в мягкой форме, для сборочных инструментов.
Практический вывод: если вы выбираете между «взять каркас, который всё свяжет» и «вызвать напрямую и связать самим», данные последних месяцев на стороне второго варианта — по крайней мере в том, что касается того, что команды реально кладут в сборки.
Мы неправы, если ваша команда меняет инструменты редко и держит их годами. Тогда наши восемь недель описывают чужую суету: устойчивость инструмента для вас важнее направления его недельной кривой, а по устойчивости этот замер не говорит ничего.