Bun знову виріс — тепер із вбудованим планувальником
Bun v1.3.11 вийшов 18 березня 2026, і головна фішка — Bun.cron. Це вбудований API для реєстрації cron-задач прямо на рівні операційної системи. Більше не треба вручну редагувати crontab або городити обгортки над сторонніми бібліотеками — Bun робить це за вас, причому однаково на Linux, macOS і Windows.
Крім того: бінарник став на 4 MB легшим, з’явився Bun.sliceAnsi для коректної нарізки рядків із кольоровими кодами терміналу, і підтюнили роботу з rest-синтаксисом.
Що було не так із cron у JS-екосистемі
Планування задач у Node.js-світі — це завжди компроміс:
- Системний crontab — працює надійно, але живе окремо від коду проєкту. Нова людина в команді не знає, що на сервері є 12 cron-задач, поки не заглянить в
crontab -l. - Бібліотеки типу
node-cron— зручно, але якщо процес впаде — всі задачі зникнуть разом з ним. - Зовнішні планувальники на кшталт Kubernetes CronJob або AWS EventBridge — потужні, але надмірно складні для простих задач і прив’язують до конкретної інфраструктури.
Ідея Bun.cron інша: описуєш задачу в коді → Bun реєструє її в планувальнику ОС → задача працює навіть після того, як Bun-процес завершиться.
Bun.cron: як це працює
Реєстрація задачі
// register-jobs.ts
Bun.cron("./scripts/cleanup-logs.ts", "0 3 * * *", "cleanup-logs");
Три аргументи:
- Шлях до скрипта — який файл запускати.
- Cron-вираз — коли запускати. У прикладі
0 3 * * *означає «щодня о 3:00 ночі». - Назва — ідентифікатор задачі, щоб потім її можна було знайти або видалити.
Після виконання Bun створить запис у системному планувальнику:
- Linux → додасть у crontab
- macOS → створить launchd-сервіс
- Windows → створить запис у Task Scheduler
Валідація cron-виразів
const result = Bun.cron.parse("*/15 * * * *");
console.log(result);
// { minute: "*/15", hour: "*", dayOfMonth: "*", month: "*", dayOfWeek: "*" }
// А якщо вираз некоректний:
try {
Bun.cron.parse("banana * * *");
} catch (e) {
console.error("Невалідний cron-вираз:", e.message);
}
Bun.cron.parse() перевіряє вираз перед реєстрацією. Особливо корисно, якщо розклад приходить від користувачів або з конфігу — краще зловити помилку одразу, ніж дізнатися про неї о 3:00 ночі.
Видалення задачі
Bun.cron.remove("cleanup-logs");
Видаляє задачу з планувальника ОС за назвою. Чисто і передбачувано.
Приклад: реєстрація кількох задач
// setup-cron.ts — реєструємо три задачі одним скриптом
const jobs = [
{ script: "./jobs/db-backup.ts", cron: "0 2 * * *", name: "db-backup" },
{ script: "./jobs/send-digest.ts", cron: "0 8 * * 1", name: "weekly-digest" },
{ script: "./jobs/cleanup-temp.ts", cron: "*/30 * * * *", name: "temp-cleanup" },
];
for (const job of jobs) {
// Спочатку перевіряємо, чи коректний cron-вираз
Bun.cron.parse(job.cron);
// Якщо все ок — реєструємо в ОС
Bun.cron(job.script, job.cron, job.name);
console.log(`✅ Зареєстровано: ${job.name} (${job.cron})`);
}
У цьому прикладі: бекап бази кожну ніч о 2:00, дайджест щопонеділка о 8:00, очистка тимчасових файлів кожні 30 хвилин.
Сумісність із Cloudflare Workers
API спроєктований сумісно з Cloudflare Workers Cron Triggers. Це означає: якщо ви пишете задачу для локального Bun і потім хочете перенести її в хмару — зміни в коді будуть мінімальними. Один код, два середовища.
Бінарник на 4 MB менший
Команда Bun прибрала CMake зі свого білд-процесу. Результат: виконуваний файл Bun для Linux x64 зменшився на 4 мегабайти.
Здавалося б — 4 MB, і що? Але у контексті Docker-контейнерів і edge-серверів кожен мегабайт рахується. Менший бінарник = швидше завантаження Docker-образу, менший cold start, менший об’єм на IoT-пристроях.
Це не та фіча, заради якої ви оновите Bun. Але це показник інженерної культури: команда оптимізує не тільки runtime, а й процес збірки самого runtime.
Bun.sliceAnsi: нарізка рядків для CLI
Якщо ви будуєте CLI-інструменти, ви знаєте біль: рядок у терміналі — це не просто текст. Це суміш видимих символів, ANSI escape-послідовностей і grapheme clusters.
Стандартний String.prototype.slice() ріже по кодпоінтах і ламає і кольорові коди, і емодзі. Bun.sliceAnsi вирішує це:
import { sliceAnsi } from "bun";
const colored = "\x1b[31mHello\x1b[0m 🌍 World";
// Стандартний slice зламає кольорові коди:
console.log(colored.slice(0, 10)); // Каша з невидимих escape-кодів
// Bun.sliceAnsi враховує видиму ширину:
console.log(sliceAnsi(colored, 0, 5)); // "Hello" (червоний, з правильним закриттям ANSI)
Ідеальний варіант для:
- Таблиць у терміналі з кольоровими комірками
- Прогрес-барів із емодзі
- Обрізки тексту для фіксованої ширини колонок
Покращення rest-синтаксису
Bun v1.3.11 оптимізував внутрішню обробку rest-синтаксису. Це не нова фіча, а покращення продуктивності: операції з ... стали швидшими і використовують менше пам’яті.
// Ці патерни тепер працюють ефективніше:
const [first, ...rest] = largeArray;
const { id, ...metadata } = bigObject;
function log(message: string, ...args: unknown[]) { /* ... */ }
Якщо ваш код активно використовує деструктуризацію з rest — ви отримаєте безкоштовний приріст продуктивності після оновлення.
Антипатерни: чого не робити
❌ Реєструвати cron-задачі без валідації
// Погано: якщо вираз невалідний, дізнаєтеся тільки коли задача мала б запуститися
Bun.cron(script, userInput, name);
// Добре: перевіряй перед реєстрацією
Bun.cron.parse(userInput); // кине помилку, якщо вираз некоректний
Bun.cron(script, userInput, name);
❌ Дублювати назви задач
Якщо зареєструвати дві задачі з однаковою назвою — одна перезапише іншу без попередження. Використовуйте унікальні, описові назви.
❌ Плутати Bun.cron з таймерами всередині процесу
Bun.cron реєструє задачу в ОС — вона запускається як окремий процес за розкладом. Якщо вам потрібен таймер всередині тривалого процесу (наприклад, оновлення кешу кожні 30 секунд) — використовуйте setInterval або Bun.sleep, а не Bun.cron. Cron — для задач, які мають пережити зупинку вашого застосунку.
❌ Забувати про cleanup
Якщо ви перестали використовувати задачу — видаліть її через Bun.cron.remove(). Інакше вона залишиться в системному планувальнику і працюватиме навіть після видалення самого коду. Класична «задача-привид».
Що робити далі
- Оновити Bun:
bun upgrade— перевірте, що у вас v1.3.11 або новіша. - Інвентаризація задач: перегляньте, що зараз живе в
crontab -lабо відповідних планувальниках. Які задачі варто перенести на Bun.cron? - Пілотна міграція: візьміть одну некритичну задачу, перепишіть на Bun.cron, перевірте, що вона з’явилась у системному планувальнику.
- CLI-інструменти: якщо у вас є CLI на Bun з кольоровим виводом — спробуйте
Bun.sliceAnsiзамість кастомних рішень. - Перевірте продуктивність: якщо у вас є гарячі ділянки коду з активною деструктуризацією — порівняйте швидкість до й після оновлення.
Джерела: