Deno — среда выполнения JavaScript и TypeScript на движке V8, написанная на Rust. Она запускает код без этапа сборки, по умолчанию запрещает доступ к файлам, сети и переменным окружения, а зависимости умеет брать из реестра JSR и из npm. В 2026 году актуальна ветка Deno 2.x: в ней есть workspace, полноценная поддержка npm-пакетов и единый CLI. Разберём установку, модель разрешений, конфигурацию проекта, тесты и сборку бинарника.
Установка
Официальный установщик скачивает бинарник в ~/.deno и добавляет путь в профиль оболочки.
curl -fsSL https://deno.land/install.sh | sh
~/.deno/bin/deno --version
deno upgrade
После установки перезапустите терминал или выполните source ~/.bashrc. Проверить расположение кэша и версию можно командой deno info. Обновление до свежего релиза выполняет deno upgrade, откат — deno upgrade —version с указанием нужного номера.
Первый скрипт
Deno понимает TypeScript без tsconfig и отдельной транспиляции. Создайте файл и запустите его напрямую — компиляция произойдёт в памяти.
cat > hello.ts <<'EOF'
const name: string = Deno.args[0] ?? "мир";
console.log(`Привет, ${name}!`);
EOF
deno run hello.ts Linux
Аргументы доступны через Deno.args, типы проверяются при запуске. Для прототипа хватает одного файла: импорты разрешаются по URL или из карты deno.json, а отдельный сборщик не нужен. Для watch-режима добавьте --watch: процесс перезапустится при изменении файла.
Модель разрешений
По умолчанию скрипт не может читать файлы, ходить в сеть и получать переменные окружения. Разрешения выдаются флагами и могут быть сужены до конкретных путей и доменов. Такой подход ограничивает ущерб от чужого кода.
deno run --allow-read=/data --allow-net=api.example.com app.ts
deno run --allow-env=HOME,PATH script.ts
deno run -A risky.ts
Флаг -A выдаёт всё сразу и годится только для доверенных локальных задач. Для сервера достаточно разрешить прослушивание порта и чтение каталога со статикой. Запреты сильнее разрешений: --deny-net перекрывает --allow-net, если указаны оба.
Зависимости из JSR и npm
Deno 2 работает с реестром JSR и пакетами npm через префиксы jsr: и npm:. Команда deno add записывает зависимость в deno.json и обновляет lock-файл.
deno add jsr:@std/http
deno add npm:express
deno install
deno info
Файл deno.lock нужно хранить в репозитории: он фиксирует версии и контрольные суммы. Импорт в коде выглядит как import { serve } from "jsr:@std/http/server" или import express from "npm:express". Для приватных пакетов используйте переменные окружения с токенами, а не запись секретов в конфиг.
Конфигурация проекта
deno.json заменяет package.json и tsconfig: в нём задаются задачи, карта импортов, настройки форматтера и компилятора. Задачи запускаются через deno task и не требуют npm-скриптов.
{
"tasks": {
"dev": "deno run --watch --allow-net --allow-read main.ts",
"check": "deno check main.ts",
"test": "deno test --allow-read"
},
"imports": {
"@std/http": "jsr:@std/http@^1"
},
"fmt": { "lineWidth": 100 },
"compilerOptions": { "strict": true }
}
Карта imports позволяет использовать короткие алиасы и обновлять версии в одном месте. Для монорепозитория добавьте поле workspace со списком пакетов: зависимости будут общими, а задачи можно запускать по имени пакета.
HTTP-сервер без фреймворка
Встроенный Deno.serve покрывает типовые задачи: маршрутизацию, JSON, стриминг. Отдельный веб-сервер для простого API не нужен.
Deno.serve({ port: 8000 }, (req) => {
const url = new URL(req.url);
if (url.pathname === "/health") {
return Response.json({ ok: true, ts: Date.now() });
}
return new Response("Not found", { status: 404 });
});
Запуск: deno run --allow-net=0.0.0.0:8000 server.ts. Статический метод Response.json избавляет от ручной сборки заголовков. Для продакшена добавьте логирование, ограничение размера тела запроса и корректную обработку ошибок.
Файлы и данные
Доступ к диску открывается флагом, а пути можно ограничить каталогом проекта. Чтение и запись выполняются через стандартный модуль @std/fs или через Deno.readTextFile; для больших файлов используйте потоки, чтобы не держать всё в памяти.
const text = await Deno.readTextFile("./data.json");
const data = JSON.parse(text);
await Deno.writeTextFile("./out.json", JSON.stringify(data, null, 2));
Для CLI-утилиты удобно брать путь из аргументов и проверять его через Deno.stat. Не подставляйте пользовательский ввод в путь без нормализации: последовательность ../ может вывести за пределы каталога, который вы разрешили.
Тесты, линт и форматирование
Инструменты встроены: отдельные пакеты для тестов и линтера не нужны. Тесты пишутся через Deno.test, утверждения берутся из @std/assert.
deno fmt
deno lint
deno test --coverage=cov
deno coverage cov
Форматтер и линтер можно повесить на pre-commit hook или CI. Покрытие считается по файлам и строкам; каталог cov добавьте в .gitignore. Для строгой проверки типов без запуска используйте deno check.
Сборка и запуск
deno compile собирает один исполняемый файл со встроенным рантаймом. Это удобно для утилит, которые должны работать на машине без Deno.
deno check main.ts
deno compile --allow-net --output api server.ts
./api
deno compile --target x86_64-unknown-linux-gnu --output api-linux server.ts
Разрешения можно вшить в бинарник при компиляции, но лучше выдавать их при запуске. Кросс-компиляция поддерживает основные платформы; проверяйте результат на целевой системе, особенно если используются нативные модули. В CI кэшируйте DENO_DIR между сборками — это заметно ускоряет установку зависимостей.
Типичные ошибки
- запуск без нужного флага: сообщение PermissionDenied подсказывает, какое разрешение запросить;
- неверная версия импорта из JSR: сверьтесь с deno.lock и диапазоном в deno.json;
- смешивание API Node и Deno: для совместимости используйте префикс node:;
- забытый --allow-net при старте сервера: процесс завершится на первом же запросе.
Диагностика
Если модуль не находится, посмотрите дерево зависимостей и кэш. Переменная DENO_DIR по умолчанию указывает на ~/.cache/deno в Linux.
deno info
deno info jsr:@std/http
deno check main.ts
deno info показывает локальный кэш, размер и источники модулей. Очистить кэш можно удалением каталога, но это крайняя мера: сначала проверьте версию импорта и lock-файл.
Итог
Deno даёт цельный набор инструментов для JavaScript и TypeScript: рантайм, менеджер зависимостей, тесты, линтер, форматтер и компилятор в одном бинарнике. Модель разрешений требует дисциплины, зато снижает риск. Начните с небольшой утилиты, вынесите задачи в deno.json, зафиксируйте зависимости lock-файлом — и проект останется воспроизводимым на любой машине с Linux.