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

@karta.io/eslint-config

v2.3.0

Published

A Eslint config we use for our projects

Readme

Eslint config

Flat ESLint config for JavaScript, TypeScript, Vue 3, Prettier. Thanks to sxzz for example.

Features

  • Format with Prettier.
  • Designed to work with TypeScript and Vue 3 out-of-box.
  • Support JSON(5), YAML, Markdown...
  • Enforces the Karta import group order and sorts keys in package.json, tsconfig.json...
  • ESLint Flat config, compose easily!
  • Reasonable defaults, best practices, only one-line of config

Usage

Install

npm install @karta.io/eslint-config eslint --save-dev

# or with pnpm:
pnpm add -D @karta.io/eslint-config eslint

Requires Node.js ^20.19.0 || ^22.13.0 || >=24 and ESLint ^9.38.0 || ^10.0.0.

Both floors come from the plugins, not from ESLint itself. The Node range is declared by eslint-plugin-jsonc@3, eslint-plugin-yml@3 and eslint-plugin-n@18; the 9.38.0 floor comes from the first two, which both require eslint >=9.38.0. Staying on ESLint 9 does not lower either.

And create eslint.config.mjs in your project root:

// eslint.config.mjs
import { createConfig } from '@karta.io/eslint-config';

export default createConfig();

Add script for package.json

For example:

{
  "scripts": {
    "lint": "eslint .",
    "lint:fix": "eslint . --fix"
  }
}

Customization

We use ESLint Flat config. It provides much better organization and composition.

Normally you only need to import the createConfig function:

// eslint.config.mjs
import { createConfig } from '@karta.io/eslint-config';

export default createConfig();

And that's it! Or you can enable/disable each integration individually, for example:

// eslint.config.mjs
import { createConfig } from '@karta.io/eslint-config';

export default createConfig({
  settings: {
    // Vue is auto-detected, you can also explicitly enable or disable it:
    vue: true,

    // Disable yml and markdown support
    yml: false,
    markdown: false,

    // Disable prettier support
    prettier: false,

    // Disable jsonc support and sorting keys for package.json and tsconfig.json
    jsonc: false,
    sortKeys: false,
  },
});

The keys are exactly vue, prettier, sortKeys, markdown, jsonc and yml. In a .mjs config nothing type-checks them, so an unknown key is silently ignored — earlier revisions of this file documented yaml, which never disabled anything.

Vue detection is package-based: the Vue config turns on when vue, nuxt, vitepress or @slidev/cli resolves from the working directory. In a directory where Vue is not installed — a scratch dir, a script that lints another project's sources — .vue files are silently left unlinted. Pass vue: true explicitly when that matters.

And also you can override any rule:

// eslint.config.mjs
import { createConfig } from '@karta.io/eslint-config';

export default createConfig({
  // https://eslint.org/docs/latest/use/configure/configuration-files#configuration-objects
  config: [
    {
      files: ['**/*.ts'],
      rules: {
        '@typescript-eslint/no-redeclare': 'off',
      },
    },
    {
      files: ['**/*.vue'],
      rules: {
        'vue/no-dupe-keys': 'error',
      },
    },
  ],
});

Upgrading to 2.0.0

Four breaking changes. The first three are mechanical, the fourth is the one that produces a large diff.

ESLint 10 support, ESLint 9 kept. The peer range widens to ^9.38.0 || ^10.0.0, so you can take this version without jumping to ESLint 10 in the same step. CI here runs both ends of that range.

Node floor. See the install section above — repositories still on Node 20.12 need the runtime bump first.

Rule namespace of eslint-comments. The abandoned eslint-plugin-eslint-comments is replaced by @eslint-community/eslint-plugin-eslint-comments, so rule ids change from eslint-comments/* to @eslint-community/eslint-comments/*. This only matters if you reference those ids yourself — in an override, or in an inline eslint-disable comment.

Style-guide conventions are now enforced as rules. They used to live as prose in CLAUDE.md and were checked by eye during review:

  • import/order — full Karta group order (external → @karta.io → stores → query-client → queries → sdk → services → api → router → composables → helpers → data → mocks → seeds → enums → interfaces → assets → components), plus a blank line between rank groups;
  • vue/attributes-order — the style-guide order, which differs from the plugin default in one place: v-html / v-text come before events;
  • vue/component-api-style — <script setup> only;
  • vue/match-component-file-name — the name in defineOptions must match the file name. Note it only checks a name that exists: a component without defineOptions is not reported. That gap is covered by karta/require-component-name (warn), the package's own rule: an SFC with a <script> block must set defineOptions({ name }). Template-only files are out of scope, a non-literal name counts as set, and there is no autofix;
  • karta/match-class-name-file-name (warn) — the block passed to useClassName('…') must be the kebab-case file name (ItemCard.vue → item-card, UIButton.vue → ui-button). Only the first call in a file is checked, since later calls legitimately name child blocks; a non-literal first argument skips the file, and there is no autofix;
  • vue/padding-line-between-tags — a blank line between adjacent div blocks;
  • no-magic-numbers (warn) — a bare number inside an expression must be a named constant: a comparison, an argument, arithmetic. 0, 1, -1 and array indexes are allowed, and so is a default value (searchDelay = 300), because its name already is the constant. Three places stay out of scope by design, so do not read a clean run as "no magic numbers left": a value assigned to a variable (const timeout = 45000 — the name is the point), a property value ({ limit: 50 }, since detectObjects is off), and a numeric enum member. The property case is the one that bites: turning detectObjects on costs +152 findings in the admin panel alone, and the largest single file is a plan-price table where the numbers are the data. There is no autofix.

Three of them auto-fix: import/order, vue/attributes-order and vue/padding-line-between-tags. Expect eslint . --fix to touch a large number of files on first run, and land that run as its own commit so it stays reviewable. The rest need editing by hand — vue/component-api-style, no-magic-numbers and both karta/* rules have no fixer, and vue/match-component-file-name only offers an editor suggestion, which --fix does not apply.

Versioning

The public surface of this package is not only what it exports — it is the verdict it gives on someone else's code. So the bump is chosen by what happens in a consumer, not by how large the diff here is:

  • major — a rule turns from warn into error, or a config entry point / option is renamed or removed. Code that used to pass CI now fails it, and there is no autofix;
  • minor — a new rule, a new group, or any change to what --fix produces. Consumer code that was clean yesterday is reported today, but the fixer resolves it. Both 2.1.0 (three new import groups) and 2.2.0 (assets moved, relative *.mock dropped) are this case: they reordered imports in dozens of consumer files. A new rule with no fixer belongs here too — as long as it lands as warn, which is why every rule of ours without a fixer does. A new rule that lands as error with no fixer is major by the first bullet's own logic: it fails a consumer's CI on the bump itself, so it breaks the delivery and not just the code;
  • patch — no verdict changes anywhere: docs, internal refactor of the build, a fix to the package's own types or tests.

Consumers pin the exact version ("@karta.io/eslint-config": "2.2.0", no caret), so a bump never reaches anyone by itself — which is exactly why the number has to carry the meaning: it is the only signal of how much churn the upgrade brings before you run it.