npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@fab-orbita/qr

v1.1.1

Published

Zero-dependency QR code generator (ISO/IEC 18004) for Node.js, browsers and edge runtimes

Readme

@fab-orbita/qr

QR-генератор без зависимостей с полным соответствием ISO/IEC 18004.

🇺🇸 English version

npm version npm downloads Bundle Size License: MIT Node.js Zero dependencies Tests Coverage

40 версий · 4 уровня коррекции ошибок · 8 масок · 4 режима кодирования · 4 рендерера

@fab-orbita/qr — библиотека QR-кодов уровня production без рантайм-зависимостей. Работает везде — Node.js, браузерах, Cloudflare Workers, Deno, Bun и Vercel Edge (см. docs/ru/browser.md) — обеспечивает побайтовую идентичность с эталонной реализацией qrcode и поддерживает режим kanji, полублочный вывод в терминал и собственный PNG-энкодер.


📖 Содержание


Зачем?

Большинство QR-библиотек тянут за собой дерево транзитивных зависимостей — у одного только qrcode 3 прямых + ~15 транзитивных пакетов (pngjs, yargs, dijkstrajs и их зависимости). Каждая — потенциальный CVE, потенциальный ломающий апдейт, потенциальная атака через supply chain.

@fab-orbita/qr реализует весь конвейер ISO/IEC 18004 с нуля:

| Компонент | Типичная зависимость | @fab-orbita/qr | |---|---|---| | Поле Галуа GF(256) | gf256 | ✅ встроен | | Кодирование Рида — Соломона | reedsolomon | ✅ встроен | | PNG-энкодер | pngjs | ✅ встроен (собственный CRC-32) | | SVG-рендерер | шаблоны | ✅ встроен | | Терминальный рендерер | qrcode-terminal | ✅ встроен (полублоки) | | Таблица kanji (Shift JIS) | iconv-lite | ✅ встроен (6953 записи) | | Типы TypeScript | @types/qrcode | ✅ в комплекте |

Результат: один пакет, нулевой footprint установки, ноль CVE, детерминированные сборки.


Возможности

  • 🎯 Полное соответствие ISO/IEC 18004 — версии 1–40, уровни L/M/Q/H, все 8 масок
  • 🧠 Автовыбор маски — штрафные баллы N1–N4 с приоритетом меньшего индекса при равенстве
  • 🔤 Четыре режима кодирования — numeric, alphanumeric, byte (UTF-8), kanji (Shift JIS)
  • 🖼️ Четыре рендерера — терминал (обычный + полублоки), SVG, PNG, ASCII
  • 📦 Ноль рантайм-зависимостей — только node:zlib и node:fs/promises там, где они нужны; в браузерной сборке вообще нет импортов node:*
  • 🌍 Работает везде — Node.js, браузеры, Cloudflare Workers, Deno, Bun, Vercel Edge (матрица поддержки)
  • 🔒 Безопасность по умолчанию — XML-эскейп цветов в SVG, строгий hex-парсер для PNG, без eval, без динамических импортов
  • 🧪 Покрытие 100% — 253 теста, побайтовый паритет с qrcode на 1280 комбинациях матриц
  • 🌐 Двойной ESM + CommonJS — три entry (default, /node, /browser) со встроенными объявлениями TypeScript
  • ⚡ Быстро — на уровне qrcode, ~46 КБ gzipped ESM
  • 📝 Полная документация — справочник API, заметки о соответствии, политика безопасности, гайды по миграции

Сравнение

| Возможность | @fab-orbita/qr | qrcode | qrcode-generator | |---|:---:|:---:|:---:| | Рантайм-зависимости | 0 | 3 (+ транзитивные) | 0 | | Типы TypeScript | в комплекте | @types/qrcode | — | | Версии | 1–40 | 1–40 | 1–40 | | Уровни EC | L/M/Q/H | L/M/Q/H | L/M/Q/H | | Маски | 8 + авто | 8 + авто | 8 | | Numeric режим | ✅ | ✅ | ✅ | | Alphanumeric режим | ✅ | ✅ | ✅ | | Byte режим (UTF-8) | ✅ | ✅ | ✅ | | Режим kanji | ✅ встроен | ⚠️ нужен toSJISFunc | ❌ | | PNG-рендерер | ✅ без зависимостей | ✅ (через pngjs) | ❌ | | SVG-рендерер | ✅ | ✅ | ✅ | | Терминальный рендерер | ✅ полублоки | ⚠️ через toString({type:'terminal'}) | ❌ | | ASCII-рендерер | ✅ | ❌ | ❌ | | Streaming API | ❌ | ❌ | ❌ | | Нулевой footprint установки | ✅ | ❌ | ✅ | | Формат модулей | ESM + CJS | CJS | CJS | | Лицензия | MIT | MIT | MIT |


Установка

npm install @fab-orbita/qr

Требования:

  • Node.js ≥ 18 — либо любой современный браузер / edge-рантайм (там node:* не нужны)
  • Без шага сборки, без нативных модулей, без postinstall-скриптов

Быстрый старт

ESM (рекомендуется)

import { generateQR, qrToTerminal, qrToSVG, qrToPNG, qrToFile } from '@fab-orbita/qr';
import { writeFileSync } from 'node:fs';

const qr = generateQR('https://example.com');

console.log(qr.version);  // например, 2
console.log(qr.size);     // 25
console.log(qr.mode);     // 'byte'

// Вывод в терминал (полублоки, ~11 строк)
console.log(qrToTerminal(qr, { small: true }));

// Рендер в файлы
writeFileSync('qr.svg', qrToSVG(qr, { scale: 10, margin: 4 }));
writeFileSync('qr.png', qrToPNG(qr, { scale: 8 }));

// Или запись асинхронным хелпером
await qrToFile(qr, 'qr.png', { scale: 8 });

CommonJS

const { generateQR, qrToASCII } = require('@fab-orbita/qr');

const qr = generateQR('12345');
console.log(qrToASCII(qr));
// 1111111011101111111
// 1000001010001000001
// 1011101011101011101
// ...

Браузер

import { generateQR, qrToSVG, qrToPNG } from '@fab-orbita/qr';

const qr = generateQR('https://example.com');
document.body.innerHTML = qrToSVG(qr, { scale: 12 });

// В браузерах qrToPNG асинхронный (CompressionStream)
const bytes = await qrToPNG(qr, { scale: 8 });
const url = URL.createObjectURL(new Blob([bytes], { type: 'image/png' }));

Полная матрица поддержки окружений (включая ограничение PNG на Vercel Edge): docs/ru/browser.md.


API

generateQR(text, options?)

Генерирует символ QR-кода.

function generateQR(text: string, options?: QROptions): QRCode;

| Параметр | Тип | По умолчанию | Описание | |---|---|---|---| | text | string | — | Текст для кодирования (UTF-8) | | options.ecLevel | 'L' \| 'M' \| 'Q' \| 'H' | 'M' | Уровень коррекции ошибок | | options.version | 1..40 | авто | Фиксация конкретной версии | | options.mask | 0..7 | авто | Фиксация конкретной маски (без поиска по штрафу) | | options.mode | 'numeric' \| 'alphanumeric' \| 'byte' \| 'kanji' | авто | Фиксация режима кодирования | | options.minVersion | 1..40 | 1 | Нижняя граница автовыбора | | options.maxVersion | 1..40 | 40 | Верхняя граница автовыбора |

Возвращает объект QRCode:

interface QRCode {
  modules: boolean[][];  // true = тёмный; modules[row][col]
  size: number;          // 4 * version + 17
  version: number;       // 1..40
  ecLevel: ECLevel;
  mask: MaskPattern;     // 0..7
  mode: Mode;
}

Ошибки:

  • TypeError — text не строка
  • RangeError — опция вне диапазона, форсированный режим не может закодировать text, ни одна версия в диапазоне не вмещает данные

Рендереры

| Функция | Сигнатура | Результат | |---|---|---| | qrToTerminal | (qr, { small?: boolean }) => string | Терминальный арт (█ ▀ ▄ + пробелы) | | qrToSVG | (qr, RenderOptions) => string | Самодостаточный SVG-документ | | qrToPNG (Node) | (qr, RenderOptions) => Buffer | PNG-буфер, синхронно | | qrToPNG (браузер) | (qr, RenderOptions) => Promise<Uint8Array> | PNG-байты, асинхронно (CompressionStream) | | qrToASCII | (qr) => string | Сетка из 1 / 0 | | qrToFile (Node) | (qr, path, RenderOptions) => Promise<void> | Записывает .svg / .png / .txt / .ascii | | qrToFile (прочие) | та же сигнатура, всегда бросает | используйте qrToPNG/qrToSVG + Blob |

RenderOptions:

| Опция | Тип | По умолчанию | Описание | |---|---|---|---| | scale | number | SVG: 1, PNG: 4 | Единиц на модуль | | margin | number | 4 | Ширина тихой зоны в модулях | | dark | string | '#000000' | Цвет тёмных модулей (CSS для SVG, hex для PNG) | | light | string | '#ffffff' | Цвет светлых модулей |


Примеры

URL

const qr = generateQR('https://example.com/promo?src=qr', { ecLevel: 'M' });
await qrToFile(qr, 'promo.svg', { scale: 12 });

vCard (контакты)

const vcard = [
  'BEGIN:VCARD',
  'VERSION:3.0',
  'N:Fabricius;Vladimir;;;',
  'FN:Фабрициус Владимир Николаевич',
  'ORG:ООО ДЕВОРБИТ',
  'EMAIL:[email protected]',
  'END:VCARD',
].join('\n');

const qr = generateQR(vcard, { ecLevel: 'Q' });  // Q защищает контактные данные
await qrToFile(qr, 'vcard.png', { scale: 8 });

Wi-Fi

function wifiQr(ssid: string, password: string, security: 'WPA' | 'WEP' | 'nopass' = 'WPA') {
  const esc = (s: string) => s.replace(/([\\;,:"])/g, '\\$1');
  const body = security === 'nopass'
    ? `WIFI:T:nopass;S:${esc(ssid)};;`
    : `WIFI:T:${security};S:${esc(ssid)};P:${esc(password)};;`;
  return generateQR(body, { ecLevel: 'H' });  // H: переживает печать и блики
}

await qrToFile(wifiQr('Orbita-5G', 's3cret!pass'), 'wifi.svg', { scale: 10 });

2FA / TOTP (otpauth URI)

const otpauth =
  'otpauth://totp/Example:[email protected]' +
  '?secret=JBSWY3DPEHPK3PXP&issuer=Example&algorithm=SHA1&digits=6&period=30';

const qr = generateQR(otpauth, { ecLevel: 'M' });
console.log(qrToTerminal(qr, { small: true }));  // можно сразу вставить в CLI

Режим kanji

// Только явно — kanji никогда не определяется автоматически.
const qr = generateQR('東京タワー', { mode: 'kanji', ecLevel: 'M' });
console.log(qr.mode);  // 'kanji'
console.log(qr.version);  // 1 (kanji очень компактен)

// Символы вне Shift JIS вызывают понятную ошибку:
generateQR('東京🙂', { mode: 'kanji' });
// RangeError: character U+1F642 "🙂" cannot be encoded in Kanji mode (not in Shift JIS)

Терминальный арт в логах CI

const qr = generateQR('https://ci.example.com/build/42');
process.stdout.write(qrToTerminal(qr, { small: true }) + '\n');

Кастомные стили

const dark = '#101820';
const light = '#FFFBF0';

const qr = generateQR('hello', { ecLevel: 'Q' });
const svg = qrToSVG(qr, { scale: 16, margin: 4, dark, light });
const png = qrToPNG(qr, { scale: 8, margin: 4, dark, light });

Ограниченные версии

// Как минимум версия 7 (например, чтобы гарантировать блоки version info в тестах)
generateQR('hi', { minVersion: 7 });

// Никогда не выше версии 5 — бросит ошибку, если данные не влезают
generateQR('hi', { maxVersion: 5, ecLevel: 'H' });

Больше рецептов: docs/ru/examples.md.


Превью рендеринга

Терминал (по умолчанию)

██████████████      ██████  ███████████████
██          ██        ██    ██          ██
██  ██████  ██  ██  ██  ██  ██  ██████  ██
██  ██████  ██  ██    ████  ██  ██████  ██
██  ██████  ██  ██████████  ██  ██████  ██
██          ██  ████    ██  ██          ██
██████████████  ██  ██  ██  ███████████████
                ██    ████
██  ██████████          ██  ██████████
...

Терминал (small: true) — полублоки

█▀▀▀▀▀█   ▀█▀ █▀▀▀▀▀█
█ ███ █ █ ▀▄█ █ ███ █
█ ▀▀▀ █ ██▀▀█ █ ▀▀▀ █
▀▀▀▀▀▀▀ █ ▀▄█ ▀▀▀▀▀▀▀
▀ ▀▀█▀▀▄▄▄  █ ▀█▀██▄▄
▀▀▄▄▀▀▀▀ ▄ ▀ ▀ ▄█▀  ▀
    ▀▀▀▀▄ ██▄█▄ ▀▄▀▄▄
█▀▀▀▀▀█ ▄▄▄▄█▄█▀ ▄▀ █
█ ███ █ █ ▀ █  █  █
█ ▀▀▀ █ ▀ ▄▀ ▀ ▄█ █ ▄
▀▀▀▀▀▀▀ ▀ ▀▀ ▀  ▀ ▀

ASCII

111111100011101111111
100000100001001000001
101110101010101011101
...

SVG / PNG

Стандартные изображения QR — сканируются любым считывателем.


Производительность

Замер npm run bench — 10 000 итераций на вход после прогрева в 500 итераций, Node.js v22.23.3 (Linux x64). Таблица ниже — один записанный прогон (2026-10-08) — см. docs/ru/performance.md: запись из двух прогонов и оговорки, прежде чем делать выводы.

| Вход | @fab-orbita/qr | qrcode | Сравнение | |---|---:|---:|---| | URL (https://example.com/test) | 2 412 мс | 2 393 мс | fab-qr на 0,8% медленнее | | Английский текст (44 символа) | 4 167 мс | 4 661 мс | fab-qr на 10,6% быстрее | | 40 цифр | 2 336 мс | 2 195 мс | fab-qr на 6,4% медленнее |

Размер бандла (все три entry, node scripts/analyze.mjs):

| Артефакт | Raw | Gzip | Brotli | |---|---:|---:|---:| | dist/index.js (универсальный, ESM) | 173.8 KB | 45.5 KB | 41.6 KB | | dist/index.node.js (Node, ESM) | 173.7 KB | 45.3 KB | 41.5 KB | | dist/index.browser.js (браузер, ESM) | 173.8 KB | 45.5 KB | 41.6 KB |

Основная часть размера — закоммиченная таблица kanji (Unicode → Shift JIS, 6953 записи в виде чистого литерала Uint16Array, без рантайм-декодирования); hex-литералы хорошо сжимаются gzip. CI падает, если gzip любого артефакта превысит 100 КБ.

Полная методология: docs/ru/performance.md.


Соответствие ISO/IEC 18004

@fab-orbita/qr нацелен на полное соответствие ISO/IEC 18004.

| Раздел / возможность | Статус | |---|:---:| | Версии 1–40 (Таблица 1) | ✅ | | Уровни коррекции ошибок L / M / Q / H | ✅ | | Структура EC-блоков — все 160 комбинаций (Таблица 9) | ✅ | | Рид — Соломон над GF(256), полином 0x11D | ✅ | | Чередование блоков | ✅ | | Режимы: numeric, alphanumeric, byte (UTF-8), kanji (Shift JIS) | ✅ | | Индикатор режима и ширины счётчика символов | ✅ | | Терминатор, битовый padding, pad-кодворды 0xEC/0x11 | ✅ | | Finder-паттерны + разделители | ✅ | | Alignment-паттерны (формула, включая случай v32 со шагом 26) | ✅ | | Timing-паттерны | ✅ | | Тёмный модуль в (4v + 9, 8) | ✅ | | Зигзагоидная раскладка данных | ✅ | | Маски 0–7 | ✅ | | Штрафные правила N1, N2, N3, N4 | ✅ | | Автовыбор маски | ✅ | | Format information BCH(15,5), обе копии | ✅ | | Version information BCH(18,6) для v7–40 | ✅ | | Тихая зона | ✅ | | Structured append, ECI, FNC1, Micro QR, rMQR | ❌ вне области |

Интерпретационные решения (документированы в docs/ru/compliance.md):

  • N4-штраф зафиксирован за семантикой qrcode (ceil, не floor)
  • N3 со светлыми зонами с обеих сторон считается дважды
  • Kanji никогда не определяется автоматически (неоднозначно для кириллицы/BMP)
  • Счётчик byte-режима = байты UTF-8 (по стандарту)
  • Пустой вход разрешён (qrcode бросает ошибку)

Стратегия верификации:

  • 1280 сравнений матриц (v1–40 × EC × маска) с [email protected] — ноль различий
  • Паритет автоверсии и автмаски на фиксированном корпусе и fuzz из 200 строк с сидом
  • Сверка BCH-слов format/version для всех комбинаций
  • Проверка нулевых синдромов Рида — Соломона
  • E2E-декод через OpenCV в CI (см. .github/workflows/ci.yml)

Миграция с других библиотек

С qrcode (node-qrcode)

// Было
import QRCode from 'qrcode';
await QRCode.toFile('qr.png', text, { errorCorrectionLevel: 'H', width: 300 });
const svg = await QRCode.toString(text, { type: 'svg' });

// Стало
import { generateQR, qrToFile, qrToSVG } from '@fab-orbita/qr';
await qrToFile(generateQR(text, { ecLevel: 'H' }), 'qr.png', { scale: 75 });
const svg = qrToSVG(generateQR(text), { scale: 8 });

| qrcode | @fab-orbita/qr | |---|---| | errorCorrectionLevel: 'M' | ecLevel: 'M' | | version: 5 | version: 5 | | maskPattern: 3 | mask: 3 | | QRCode.toDataURL / toBuffer | qrToPNG (Buffer) | | QRCode.toString(text, {type:'terminal'}) | qrToTerminal(qr, { small: true }) | | QRCode.create(text) | generateQR(text) | | width / margin (пиксели) | scale + margin (модули) | | callback / promise API | синхронные рендереры + асинхронный qrToFile |

Отличия, о которых стоит знать:

  • Вывод синхронный — промисов нет, кроме qrToFile
  • modules — это boolean[][], а не упакованный Uint8Array
  • Один режим на символ (выберите сами или доверьтесь автопределению лучшего единичного режима)
  • Пустой вход здесь разрешён (qrcode бросает ошибку)
  • Kanji работает сразу (qrcode требует toSJISFunc)

С qrcode-generator

// Было
import qrcode from 'qrcode-generator';
const qr = qrcode(0, 'M');
qr.addData('hello');
qr.make();
qr.createImgTag(4);

// Стало
import { generateQR, qrToSVG, qrToPNG, qrToTerminal } from '@fab-orbita/qr';
const qr = generateQR('hello', { ecLevel: 'M' });
qrToSVG(qr, { scale: 4 });
qrToPNG(qr, { scale: 4 });
qrToTerminal(qr, { small: true });

Полный гайд: docs/ru/migration.md.


Тестирование

npm test              # запустить все тесты
npm run test:watch    # режим наблюдения
npm run test:coverage # с отчётом покрытия

Набор тестов:

  • 253 теста в 28 файлах
  • Покрытие statements, branches, functions, lines — 100%
  • Побайтовый паритет с [email protected] для всех 1280 комбинаций версия × EC × маска
  • Property-based fuzzing (200 случайных входов с сидом)
  • Тесты сквозного кодирования: generateQR → qrToPNG → декод OpenCV

FAQ

qrcode — отличная библиотека, но у неё 3 прямых + ~15 транзитивных зависимостей (pngjs, yargs, dijkstrajs и т.д.). Каждая — потенциальный CVE. У @fab-orbita/qr ноль рантайм-зависимостей, и всё реализовано с нуля:

  • Меньший footprint установки
  • Детерминированные сборки
  • Нет поверхности атаки через supply chain
  • Встроенный режим kanji (без инъекции toSJISFunc)
  • Полублочный вывод в терминал

Да — официально, начиная с v1.1.0. Пакет поставляет отдельный браузерный entry с нулём импортов node:* (проверяется в CI):

import { generateQR, qrToSVG, qrToPNG } from '@fab-orbita/qr';
const bytes = await qrToPNG(generateQR('hello')); // асинхронно, CompressionStream

Работает в браузерах, Cloudflare Workers, Deno и Bun. На Vercel Edge qrToPNG бросает ошибку (там нет ни CompressionStream, ни node:zlib) — используйте qrToSVG. Подробности: docs/ru/browser.md.

  • @fab-orbita/qr: 173.8 KB raw / 45.5 KB gzip (ESM, включая таблицу kanji)
  • qrcode + зависимости: обычно ~120–200 KB в зависимости от tree-shaking
  • Японский (kanji): ✅ нативная поддержка через mode: 'kanji'
  • Китайский/корейский: ⚠️ используйте mode: 'byte' (UTF-8) — определяется автоматически при неалфавитных символах
  • L — восстановление ~7%
  • M — ~15% (по умолчанию, лучший баланс)
  • Q — ~25%
  • H — ~30% (лучше для печати и условий бликов)

Да — передайте version (1–40) и/или mask (0–7) в generateQR. Фиксация mask пропускает поиск по штрафу (быстрее, но качество символа может быть ниже).

Нет. Определение Shift JIS неоднозначно для кириллицы и другого BMP-текста (например, А в кириллице и ア в катакане могут иметь перекрывающиеся байтовые диапазоны). Передавайте mode: 'kanji' явно.

Да. Одинаковый вход + одинаковые опции → побайтово идентичный вывод на всех платформах и версиях Node.js. Таблица kanji зафиксирована в исходниках (не генерируется в рантайме), поэтому различий ICU нет.


Документация

Английские версии: docs/.


Разработка

git clone https://github.com/zammartin2/qr.git
cd qr
npm install

npm run lint          # eslint, ноль предупреждений
npm run typecheck     # tsc --noEmit
npm run test:coverage # пороги должны быть зелёными
npm run build         # rm -rf dist && tsup (3 entry)
npm run test:bundle   # esbuild-гейты + проверки exports/d.ts
npm run bench         # бенчмарк производительности
npm run docs:check    # JSDoc обязателен на каждом публичном экспорте
node scripts/analyze.mjs  # гейт размера бандла (gzip ≤ 100 КБ)

Принципы:

  • Ноль рантайм-зависимостей (только встроенные модули Node)
  • Спецификация прежде всего: ссылайтесь на пункты ISO/IEC 18004 в изменениях
  • Требуется 100% покрытие тестами
  • JSDoc на всех публичных экспортах

Полные правила: CONTRIBUTING.md.


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

Сообщайте об уязвимостях на [email protected] — не открывайте публичный GitHub issue для сообщений о проблемах с безопасностью.

  • Ноль рантайм-зависимостей → CVE третьих сторон невозможны
  • SVG-вывод XML-эскейпит цвета (нет инъекции разметки)
  • PNG-вывод использует строгий парсер #RGB/#RRGGBB
  • Без eval, без динамических импортов пользовательских данных, без shell-out'ов

См. SECURITY.md и docs/ru/security.md.


Участие

Вклад приветствуется! Прочитайте CONTRIBUTING.md и CODE_OF_CONDUCT.md перед открытием PR.

Короткий чек-лист:

  • [ ] Тесты проходят (npm run test:coverage)
  • [ ] Lint чистый (npm run lint)
  • [ ] Type-check чистый (npm run typecheck)
  • [ ] JSDoc на публичных экспортах
  • [ ] Новых рантайм-зависимостей нет

Лицензия

MIT © Фабрициус Владимир Николаевич / ООО «ДЕВОРБИТ»


⭐ Звезда на GitHub · 📦 Пакет на npm · 🐛 Сообщить о баге Сделано с ❤️ в Сибири