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

@37bytes/code-style

v0.0.5

Published

Unified linting and formatting configs for 37bytes projects

Downloads

791

Readme

@37bytes/code-style

0.0.5: пакет в активной разработке. API может меняться без предупреждения.

Точка входа для инструментов поддержки качества проектов 37bytes

Установка

npm install @37bytes/code-style --save-dev

Обязательные peer-зависимости (версии фиксированы):

npm install eslint@^10.4.0 [email protected] [email protected] --save-dev

Опционально:

npm install [email protected] --save-dev     # CSS/SCSS линтинг
npm install [email protected] --save-dev         # гибридный режим OxLint
npm install @biomejs/[email protected] --save-dev  # гибридный режим Biome

ESLint

Конфиги по типу приложения: spa, nextjs, nodejsRuntime, nodejsTool.

// SPA (Vite + React)
import { spa } from '@37bytes/code-style/eslint';

export default [...spa];
// Next.js
import { nextjs, nextjsServerConfig } from '@37bytes/code-style/eslint';

// nextjsServerConfig — pre-configured glob для App Router server-side файлов
// (page.tsx, layout.tsx, route.ts, pages/api/**, *.server.{ts,tsx} и т.д.)
export default [...nextjs, nextjsServerConfig];
// Node.js production runtime — strict baseline для HTTP handlers,
// services, бизнес-логики, библиотечного кода.
import { nodejsRuntime, nodejsConfig } from '@37bytes/code-style/eslint';

export default [
    ...nodejsRuntime,
    // bootstrap/config-файлы: env-loader, server entry, scripts, migrations
    {
        files: ['src/env.ts', 'src/server.ts', 'src/main.ts'],
        ...nodejsConfig
    }
];
// CLI-утилита / one-shot script — весь код bootstrap-like
import { nodejsTool } from '@37bytes/code-style/eslint';

export default [...nodejsTool];

Срез по lifecycle

nodejsConfig это override-объект который релакс'ит правила для bootstrap-фазы:

  • n/no-process-env — env-loader как single source of truth
  • no-console — логирование до инициализации логгера
  • n/no-process-exit — fast-fail на невалидном конфиге
  • security/detect-non-literal-fs-filename — динамические .env.${envName} пути

Применяется через flat-config files-glob к нужному срезу проекта. Не имеет встроенного glob: каждый проект решает сам что у него bootstrap.

Дополнительные слои

Добавляются через spread после основного конфига:

import { spa, testingConfig, testingReactConfig, storybookConfig } from '@37bytes/code-style/eslint';

export default [...spa, ...testingConfig, ...testingReactConfig, ...storybookConfig];

| Слой | Описание | | --------------------- | -------------------------------------- | | testingConfig | Vitest + смягченные правила для тестов | | testingReactConfig | Testing Library + jest-dom | | storybookConfig | Правила Storybook | | reactCompilerConfig | Правила React Compiler | | createFSDConfig() | Ограничения архитектуры FSD |

Perfectionist (опциональная автосортировка)

import { perfectionist } from '@37bytes/code-style/eslint';

export default [
    ...perfectionist.spa
    // или perfectionist.nextjs, perfectionist.nodejsRuntime, perfectionist.nodejsTool
];

Кастомные плагины @37bytes

| Правило | Описание | | --------------------------------- | ------------------------------------------------------------ | | @37bytes/no-browser-storage | Запрет прямого доступа к localStorage/sessionStorage | | @37bytes/no-arrow-props | Запрет стрелочных функций в JSX-пропсах | | @37bytes/boolean-naming | Обязательные префиксы булеанов (is/has/should/...) | | @37bytes/enum-pattern | Запрет enum, as const + UPPER_CASE | | @37bytes/no-slice-self-import | Запрет импорта слайса через собственный public API | | @37bytes/require-server-only | Обязательный импорт server-only в серверных FSD-модулях | | @37bytes/require-client-only | Обязательная директива use client в клиентских FSD-модулях | | @37bytes/no-legacy-folders | Запрет устаревших каталогов-свалок в FSD | | @37bytes/no-redundant-undefined | Запрет лишнего undefined в optional-типах | | @37bytes/jsx-boolean-value | Единый стиль булевых JSX-пропсов | | @37bytes/jsx-fragments | Единый стиль JSX-фрагментов |

OxLint (опционально)

Готовый конфиг для гибридного режима OxLint + ESLint:

import { config } from '@37bytes/code-style/oxlint';

Подробнее: docs/oxlint.md.

Biome (опционально)

Готовый конфиг для гибридного режима Biome + ESLint:

import { config } from '@37bytes/code-style/biome';

Stylelint (опционально)

Конфиг для CSS/SCSS модулей: порядок свойств, lowerCamelCase селекторы, запрет type-селекторов, обязательные CSS-переменные для цветов/z-index/шрифтов.

npm install [email protected] --save-dev
// .stylelintrc.js
import { config } from '@37bytes/code-style/stylelint';

export default config;

Основано на stylelint-config-standard-scss. Включает плагины stylelint-order и stylelint-declaration-strict-value.

Dependency Cruiser (опционально)

Граф-уровневые правила: циркулярные зависимости, ненужные пакеты, неразрешимые импорты, dev-зависимости в production-коде, а для FSD-проектов — матрица слоёв, изоляция слайсов с @x cross-imports, обязательное публичное API, изоляция сегментов, маркеры server-only/client-only.

Дополняет ESLint-пресеты, не заменяет их: правила уровня спецификатора (порядок импортов, server-only первой строкой, запрет legacy-папок, alias vs relative) остаются в @37bytes/code-style/eslint.

Если проект гоняет и dependency-cruiser, и eslint-FSD, передай createFSDConfig({ dependencyCruiser: true }). Из eslint уберутся два правила, которые dependency-cruiser заменяет полностью: import-x/no-restricted-paths (направление слоёв) и @37bytes/no-slice-self-import. import-x/no-internal-modules остаётся намеренно: dependency-cruiser покрывает только его FSD-половину (public API слайсов), а запрет deep-import в резолвящиеся внешние пакеты (пакет/lib/внутренний/файл) не покрывает никто в графе. Также остаются порядок импортов, запрет legacy-папок, server-only/client-only первой строкой. Побочный эффект: нарушения public API FSD будут под двойным контролем (eslint в редакторе + dependency-cruiser в CI), но это редундантный сигнал на реальном нарушении, не шум. Передавай флаг, только если реально запускаешь dependency-cruiser в CI, иначе направление слоёв не проверяет никто.

Установка

npm install [email protected] [email protected] --save-dev

TypeScript нужен dependency-cruiser для разбора .ts-файлов. Без него файлы молча пропускаются. Проверить: npx depcruise --info.

Использование

// .dependency-cruiser.mjs (.mjs обязателен: пакет ESM, а дефолтный .js в большинстве проектов будет CommonJS)
import { createFsdCruiserConfig } from '@37bytes/code-style/dependency-cruiser';

export default createFsdCruiserConfig();

Для проектов без FSD:

import { createBaseCruiserConfig } from '@37bytes/code-style/dependency-cruiser';

export default createBaseCruiserConfig();

Запуск:

npx depcruise --config .dependency-cruiser.mjs src

Опции фабрик

createFsdCruiserConfig(options?):

| Опция | По умолчанию | Описание | | ------------------------ | ----------------- | --------------------------------------------------------- | | sourceRoot | 'src' | Корневая папка исходников | | tsConfigFileName | 'tsconfig.json' | Путь к tsconfig | | includeBaseRules | true | Включить базовые правила гигиены зависимостей | | extraPublicApiPatterns | [] | Дополнительные паттерны файлов, считающихся публичным API |

createBaseCruiserConfig(options?):

| Опция | По умолчанию | Описание | | ------------------ | ----------------- | --------------- | | tsConfigFileName | 'tsconfig.json' | Путь к tsconfig |

Принятие на существующем проекте

Первый запуск на живом проекте обычно даёт нарушения. Рабочий подход: зафиксировать текущее состояние как baseline и запускать с --ignore-known.

# Сохранить текущие нарушения как baseline (output-type baseline даёт плоский массив,
# который и ожидает --ignore-known; output-type json вернёт другой формат-конверт {modules:[...]})
npx depcruise --config .dependency-cruiser.mjs --output-type baseline src > .dependency-cruiser-known-violations.json

# Запускать в CI, игнорируя baseline (срабатывает только на новых нарушениях)
# src идёт ДО --ignore-known: у флага опциональный аргумент, и позиционный src после него
# будет проглочен как имя baseline-файла, после чего depcruise выведет usage-хелп
npx depcruise --config .dependency-cruiser.mjs src --ignore-known

Файл .dependency-cruiser-known-violations.json добавить в репозиторий. По мере устранения legacy-нарушений файл уменьшается.

Prettier

// prettier.config.js
import { config } from '@37bytes/code-style/prettier';

export default config;

4 пробела, одинарные кавычки, без trailing commas, точки с запятой, 120 символов.

TypeScript

{
    "extends": "@37bytes/code-style/typescript/react"
}

| Конфиг | Описание | | ------------------ | --------------------------------- | | typescript/base | Строгий базовый конфиг (ES2023) | | typescript/react | React-приложение (DOM types, JSX) | | typescript/node | Node.js (NodeNext modules) |

TypeScript 7 (Native Preview)

TypeScript 7.0 это Go-портированный компилятор Microsoft (анонс 2026-04-21), распространяется как @typescript/native-preview с бинарём tsgo. Семантика проверки типов идентична TS 6.0, скорость в среднем ~10× выше. Стабильный programmatic API ожидается в 7.1.

С нашим preset работает частично: tsgo годится для CLI-typecheck, но stable JS Compiler API ещё не выпущен, поэтому @typescript-eslint (peer cap <6.1.0) и type-aware ESLint правила TS 7 не поддерживают. Microsoft рекомендует side-by-side использование с TS 6.

Что работает с tsgo прямо сейчас

| Компонент | Статус | Как | | --------------------------------------------- | ------ | ----------------------------------------------------------- | | tsgo --noEmit для быстрого pre-flight | ок | Локальный typecheck в dev-цикле, см. caveat ниже про CI | | oxlint-tsgolint (type-aware lint от oxlint) | ок | Использует Go-based tsgolint, не зависит от JS Compiler API | | Все ESLint правила без type info | ок | AST-only, к runtime TS не привязаны | | Biome, Prettier, Stylelint, oxlint без -tsgo | ок | Независимы от TS |

Что не работает с tsgo до TS 7.1

  • @typescript-eslint/parser и type-aware правила (@typescript-eslint/*, type-aware часть @eslint-react).

Side-by-side рецепт

Пока tsgo в preview, tsc --noEmit остаётся authoritative typecheck в CI. tsgo даёт ~10× ускорение для локального pre-flight, но Microsoft явно маркирует пакет 0-dev.YYYYMMDD и шипает новую сборку ежедневно — мелкие расхождения между tsc и tsgo возможны и временами случаются. Полагаться на tsgo как на единственный CI-чек преждевременно.

Установить оба:

pnpm add -D typescript@6 @typescript/[email protected]

Версия @typescript/native-preview фиксируется датированным dev-релизом, не @beta тегом — последний двигается каждый день и сделает рецепт нестабильным. Обновляй pin вручную по мере необходимости, пока не выйдет TS 7.0 stable.

В package.json сценариях:

{
    "scripts": {
        "typecheck": "tsc --noEmit",
        "typecheck:fast": "tsgo --noEmit",
        "lint:eslint": "eslint --max-warnings 0 ."
    }
}

typecheck остаётся ground truth для CI и pre-commit. typecheck:fast для локальных итераций когда нужна скорость, не корректность последней инстанции. ESLint и редактор продолжают использовать typescript@6 через @typescript-eslint. Конфликтов между tsc и tsgo бинарями нет; Microsoft также публикует @typescript/typescript6 с tsc6 если нужна полная изоляция.

EditorConfig

cp node_modules/@37bytes/code-style/editorconfig/.editorconfig .

Browserslist

Утилита browserslist принимает extends только для пакетов с именем browserslist-config-* или @scope/browserslist-config-*. Имя @37bytes/code-style под этот шаблон не подходит, поэтому пресет нельзя подключить через extends @37bytes/code-style/browserslist (выдаст BrowserslistError: Browserslist config needs 'browserslist-config-' prefix).

Рабочий вариант инлайнить массив правил в package.json:

{
    "browserslist": [
        "last 2 Chrome versions",
        "last 2 Edge versions",
        "last 2 Opera versions",
        "last 2 Firefox versions",
        "Firefox ESR",
        "Firefox 128",
        "last 3 Safari major versions",
        "last 3 ChromeAndroid versions",
        "last 3 iOS major versions",
        "last 2 Samsung versions",
        "last 1 op_mob version"
    ]
}

Источник правды массива: browserslist/index.cjs. Если меняется в пресете надо синхронизировать вручную в потребителях. Программный доступ из JS-конфигов:

const browserslistConfig = require('@37bytes/code-style/browserslist');

Naming Conventions

См. NAMING_CONVENTIONS.md.

Лицензия

ISC