Перейти к содержимому
runtly

macOS · Node, Bun, Deno, pnpm, yarn

Какие из ваших проектов работают на среде с истёкшей поддержкой?

Любой менеджер версий скажет, на какой версии вы сейчас. runtly скажет ещё: какие версии перестали получать патчи безопасности, какие проекты на них стоят и над какими из них ещё работают.

Скачать для macOS — бесплатноUniversal · Apple Silicon и Intel · macOS 10.15+

или только командная строка

$curl -fsSL https://runtly.flatium.com/download | sh
rt audit
$ rt auditruntly audit7 projects, 1 runtime versions examined · data fetched 3 minutes agoactive project, unsupported runtime  node 18.20.4    EOL 502d ago medium      medium CVE-2025-23085 GOAWAY HTTP/2 frames cause memory leak outside heap      https://nodejs.org/en/blog/vulnerability/january-2025-security-releases/      /Users/you/code/billing-worker      /Users/you/code/checkout-api      /Users/you/code/docs-site      and 4 more      4 of 7 committed to in the last 90 days, 4 inherit the global defaultrt install node@18.20.6rt use node@18.20.6  (4 project(s) inherit the default and are fixed by this alone)runtly audit examines the runtime, not your dependency tree. It does not replace `npm audit`.

01Проблема

Менеджер версий знает номер. Он не знает риск.

nvm use и его родня отвечают на один вопрос: какая версия активна прямо сейчас. Этот вопрос закрывается в момент, когда его задали, и он ничего не говорит о том, получает ли эта версия патчи.

Поэтому ответ обычно приходит снаружи: анкета по комплаенсу, проверка безопасности со стороны клиента, форма поставщика с вопросом, какие версии Node у вас в проде. К этому моменту список приходится собирать руками — открыть каждый репозиторий, прочитать каждый .nvmrc, сверить каждую версию с календарём поддержки.

runtly держит этот список. Он знает, какие версии установлены, какие проекты разрешаются в них, когда в каждый из этих проектов был последний коммит и что опубликованные бюллетени говорят о каждой версии.

02Аудит

Аудит

rt audit смотрит на каждый просканированный проект и сообщает, какие версии среды выполнения стоят за ними.

Находки отсортированы по тому, что заслуживает внимания первым

Это те самые метки, которые печатает инструмент, в том порядке, в котором он их печатает.

  1. 01

    active project, known vulnerability

    Проект с коммитами за последние 90 дней, работающий на версии с опубликованным бюллетенем.

  2. 02

    active project, unsupported runtime

    Проект, над которым ещё работают, на версии, которая больше не получает патчей безопасности.

  3. 03

    critical vulnerability

    Бюллетень уровня critical где угодно на машине, независимо от того, активен ли проект.

  4. 04

    losing security support soon

    Версия, у которой скоро кончается поддержка, — пока ещё есть время спланировать переход.

  5. 05

    dormant project on an old runtime

    Не трогали 90 дней или дольше. Сообщается, но по умолчанию свёрнуто: это не то, что нужно чинить сегодня днём.

Наименьшее обновление, закрывающее все бюллетени

Рекомендуется конкретная версия, а не мажорный номер. Для Node 18.20.4 с незакрытым январским бюллетенем 2025 года это 18.20.6, а не «переходите на 22». Тот, кого договор с клиентом держит на Node 18, второе сделать не может, а первое — может сегодня днём.

Там, где проекты не фиксируют версию, а наследуют глобальное значение по умолчанию, runtly говорит об этом прямо и добавляет одну команду, которая чинит их все разом.

Он завершается ненулевым кодом, поэтому ему место в CI

rt audit --fail-on=critical возвращает код ошибки, когда находка достигает порога. --fail-on принимает также high, medium, low, eol и never. --json печатает отчёт целиком — для всего, что захочет его прочитать.

$ rt audit --fail-on=eol$ echo $?1

Работает офлайн и честно об этом сообщает

Данные бюллетеней кэшируются на 24 часа, так что аудит работает и в самолёте. Каждый отчёт во второй строке сообщает, насколько его данные старые — data fetched 3 minutes ago или 9 hours ago.

Откуда берутся данные

endoflife.date
Календари поддержки и окончания жизненного цикла.
Node.js Security WG
База уязвимостей Node.js Security Working Group.
OSV.dev
База уязвимостей открытого кода.

03Разрешение

Разрешение

runtly поднимается вверх от рабочего каталога и берёт первый найденный ответ. Правило — побеждает ближайшее: близкий файл с низким приоритетом выигрывает у далёкого файла с высоким, поэтому участник рабочего пространства перекрывает корень монорепозитория, а не наоборот.

Порядок приоритета внутри одного каталога, от высшего
1.runtlyrcСобственный файл runtly. Его пишет rt pin.
2.nvmrcЧитается как есть, существующий репозиторий менять не нужно.
3.node-version / .bun-versionСоглашения для одной среды выполнения.
4.tool-versionsПроекты на asdf и mise.
5package.json → packageManagerПоле Corepack, для pnpm и yarn.
6package.json → enginesДиапазоны разрешаются по установленным версиям; побеждает наибольшее совпадение.

Ограничение, которое нельзя удовлетворить, — это ошибка, а не откат

Если проект просит версию, которая не установлена, runtly останавливается и говорит об этом. Он не станет молча запускать то, что случайно оказалось в PATH. Именно такая тихая подмена через неделю превращается в «локально проходит, в CI падает».

$ node --versionerror: this directory requires node `20.99.0`, and no installed version satisfies it.  Declared in: /Users/you/code/bad/.nvmrc (.nvmrc)  Install one: rt install node@20.99.0

rt current называет файл, который это решил

Ответ на вопрос «почему я на неправильной версии?» — это путь, и инструмент печатает этот путь.

$ rt current/Users/you/code/mono/packages/web  runtime  version  source  node     18.20.4  /Users/you/code/mono/packages/web/.nvmrc (.nvmrc)

04Скорость

Скорость

Шим запускается перед каждым вызовом node, поэтому он обязан не стоить ничего. Измерено с помощью hyperfine, 500 запусков.

Добавлено на вызов node
Ничего не делающий бинарник на Rust, который только вызывает exec1.9 ms
Шим runtly: разрешает версию, затем вызывает exec1.9 ms

Работа по разрешению версии бесплатна. Остаётся собственная цена macOS за запуск процесса, и убрать её нельзя ничем.

Сканирование настоящей машины136 проектов меньше чем за секунду

05Приложение

Приложение

Под CLI и GUI лежит одно общее ядро, поэтому они не могут разойтись в том, что установлено и что под угрозой. Пункт в строке меню переключает версии, не открывая окно.

Безопасность

Безопасность

Каждая используемая версия, состояние её поддержки и проекты за ней.

Среды выполнения

Среды выполнения

Установленные версии Node, Bun, Deno, pnpm и yarn и то, что доступно в апстриме.

Проекты

Проекты

Во что разрешается каждый просканированный проект и какой файл это решил.

06Границы

Чего он не делает

Преувеличить охват по безопасности хуже, чем не заявлять его вовсе: это создаёт уверенность, у которой нет оснований. Три границы, прямым текстом.

  • Он проверяет среду выполнения, а не ваше дерево зависимостей

    runtly сообщает о версиях Node, Bun и Deno, на которых работают ваши проекты. О пакетах внутри node_modules он не говорит ничего. Он не заменяет npm audit, и его запуск не заменяет запуск той команды.

  • Для Bun и Deno «ничего не найдено» значит «никто не публикует такие данные»

    Ни один из этих проектов не ведёт публичную базу бюллетеней, какая есть у Node. runtly сообщает их статус окончания поддержки и сам печатает это предупреждение, вместо того чтобы позволить чистому отчёту намекать на то, чего он знать не может.

  • Только macOS

    Apple Silicon и Intel, macOS 10.15 и новее. Сборки для Windows нет, для Linux нет, и ни одна не обещана.

07Бесплатно

Бесплатно и с закрытым исходным кодом

Бесплатный инструмент для разработчиков с закрытым кодом сразу вызывает один вопрос, поэтому вот что эта программа делает на самом деле.

Ни аккаунта, ни регистрации, ни лицензионного ключа
Скачайте и пользуйтесь. Регистрировать нечего и активировать нечего.
Никакой телеметрии и никакой аналитики
Приложение никогда не сообщает ничего о вас или о вашей машине.
Шим не касается сети
Та часть, что запускается перед каждым вызовом `node`, не делает ни одного сетевого запроса.
Загрузки проверяются до распаковки
Каждая среда выполнения сверяется с SHA256, опубликованной самим издателем. Само приложение подписано и нотаризовано Apple и поставляется универсальным бинарником.

Все сетевые запросы, которые он делает

  • nodejs.org/distЗагрузки релизов Node
  • api.github.comМетаданные релизов Bun и Deno
  • GitHub release downloadsБинарники Bun и Deno
  • registry.npmjs.orgpnpm и yarn
  • endoflife.dateКалендари поддержки
  • raw.githubusercontent.com/nodejs/security-wgБаза бюллетеней Node.js
  • api.osv.devДанные об уязвимостях открытого кода

Те же самые места, откуда вы скачивали бы руками. Больше никуда.

08Установка

Установка

Три пути, и они кладут на машину не одно и то же.

Скачать приложение

Приложение и командная строка

Перетащите в Applications, откройте и нажмите Set up now. Приложение само установит шимы и настроит вашу оболочку — терминал не нужен ни на одном шаге.

Скачать для macOSUniversal · Apple Silicon и Intel · macOS 10.15+

Homebrew

Зависит от того, какую строку вы запустите

Приложение и CLI

$brew install --cask hieuhuynh93/tap/runtly-app

Только CLI

$brew install hieuhuynh93/tap/runtly

Установщик для оболочки

Только командная строка — для серверов и CI, где окно не имеет смысла

CLI

$curl -fsSL https://runtly.flatium.com/download | sh

CLI и приложение

$curl -fsSL https://runtly.flatium.com/download | RUNTLY_WITH_APP=1 sh

Он скачивает те же подписанные бинарники, сверяет их с опубликованной SHA256 до распаковки и запускает runtly setup за вас.

Скрипт, который он запускает, — если хотите сначала прочитать: https://dl.runtly.flatium.com/install.sh

Каким путём вы бы ни пошли, итог один: ~/.runtly/bin в PATH, а rt doctor показывает зелёное.