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

@poupe/eslint-config

v0.10.0

Published

Sharable ESLint configuration preset for Poupe UI projects with TypeScript, Vue.js, and Tailwind CSS support

Readme

@poupe/eslint-config

Sharable ESLint configuration preset for Poupe UI projects with TypeScript, Vue.js, and Tailwind CSS support.

✅ Includes:

Getting started

[!NOTE] This preset uses the new ESLint flat config format and supports ESLint v9 or v10 on Node.js 20.19+, 22.13+, or 24+.

eslint and @eslint/js are peer dependencies — the preset does not bundle them, so you must install them yourself alongside it:

pnpm install -D eslint @eslint/js typescript @poupe/eslint-config

Create eslint.config.mjs in your project root:

// @ts-check
import poupeConfig from '@poupe/eslint-config';

export default poupeConfig;

For Nuxt.js applications (with @nuxt/eslint):

// @ts-check
import { withPoupe } from '@poupe/eslint-config';
import withNuxt from './.nuxt/eslint.config.mjs';

export default withPoupe(withNuxt(), {
  rules: {
    // custom rule overrides
  },
});

For Nuxt modules (with @nuxt/eslint-config):

// @ts-check
import { createConfigForNuxt } from '@nuxt/eslint-config/flat';
import { withPoupe } from '@poupe/eslint-config';

export default withPoupe(createConfigForNuxt({
  features: {
    tooling: true,    // Enables rules for module authors
    stylistic: true,  // Enables formatting rules
  },
}));

Custom configuration:

// @ts-check
import { defineConfig } from '@poupe/eslint-config';

export default defineConfig({
  rules: {
    // rule overrides
  },
});

CSS Support

This configuration includes advanced CSS linting with Tailwind CSS v4 syntax support. The CSS configuration uses an intelligent filtering system that:

  • Applies CSS-specific rules from @eslint/css
  • Supports Tailwind CSS v4 syntax including theme functions and modifiers
  • Automatically disables JavaScript-specific rules for CSS files
  • Keeps relevant cross-language rules (like filename-case from unicorn)

The filtering system categorizes plugins and rules to ensure only appropriate rules apply to CSS files. See AGENTS.md for implementation details.

Supported File Types

This configuration automatically lints the following file types:

  • JavaScript: .js, .mjs, .cjs
  • TypeScript: .ts, .tsx
  • Vue.js: .vue (Single File Components)
  • JSON/JSONC: .json, .jsonc, package.json
  • Markdown: .md
  • CSS: .css, .postcss, Vue <style> blocks (with Tailwind CSS v4 syntax support)

Features

Self-Dogfooding

This package uses its own ESLint configuration for validation, ensuring quality and serving as a real-world test case.

Automatic Import/Export Sorting

This configuration includes eslint-plugin-perfectionist which automatically organizes your imports and exports. The sorting happens automatically when you run eslint --fix or save files with ESLint auto-fix enabled in your editor:

// Before
import { z } from 'zod';
import React from 'react';
import { useState, useEffect } from 'react';
import { Button } from './components/Button';
import axios from 'axios';
import type { User } from '../types';
import { config } from './config';

// After (automatically fixed by ESLint)
import type { User } from '../types';

import axios from 'axios';
import React from 'react';
import { z } from 'zod';

import { config } from './config';
import { Button } from './components/Button';
import { useEffect, useState } from 'react';

Import Grouping with Empty Lines

The configuration respects empty lines as block separators, allowing you to organize imports into logical groups:

// Core React imports
import React from 'react';
import { useState, useEffect } from 'react';

// External libraries
import axios from 'axios';
import { z } from 'zod';

// Internal modules
import { config } from './config';
import { Button } from './components/Button';

Each group separated by empty lines is sorted independently, preserving your intended organization while maintaining consistent ordering within each group.

Union and Intersection Type Sorting

Union and intersection types are sorted in natural order. Use comments to create logical groups:

// Before
type Status = 'error' | 'loading' | 'success' | 'idle';

// After (automatically fixed by ESLint)
type Status = 'error' | 'idle' | 'loading' | 'success';

// With comment-based grouping
type Status =
  // Active states
  | 'loading'
  | 'processing'
  // Inactive states
  | 'error'
  | 'idle'
  | 'success';

Additional Sorting Rules

The configuration also sorts these constructs in natural alphabetical order, all auto-fixable via eslint --fix:

  • Interfaces and object types — sorted by property name, with blank-line grouping support
  • Enums — sorted by member name (numeric enums sorted by value)
  • Classes — sorted by member type and visibility (static first, then instance, public before private), with blank-line grouping
  • Heritage clausesextends and implements lists
  • Variable declarations — destructured bindings
  • Import/export attributesimport ... with { ... } keys

Advanced Configuration

Custom Rule Overrides

// @ts-check
import { defineConfig } from '@poupe/eslint-config';

export default defineConfig({
  rules: {
    // Disable specific rules
    'unicorn/filename-case': 'off',

    // Customize rule severity and options
    '@typescript-eslint/no-unused-vars': ['warn', {
      argsIgnorePattern: '^_',
      varsIgnorePattern: '^_',
    }],
  },
});

Selective Configuration Import

// @ts-check
import { configs, withConfig } from '@poupe/eslint-config';

// Import only specific configurations
export default withConfig(
  configs.javascript,
  configs.typescript,
  configs.stylistic,
  configs.vue,
  // Add custom overrides
  {
    rules: {
      'vue/multi-word-component-names': 'off',
    },
  },
);

Combining Configs from Multiple Sources

When composing configs from different packages, use withPoupe to layer Poupe configs on top of an upstream config. It handles async resolution and deduplicates plugin instances automatically:

// @ts-check
import { withPoupe } from '@poupe/eslint-config';
import someOtherConfig from 'some-other-eslint-config';

export default withPoupe(someOtherConfig);

For lower-level control, reconcilePlugins deduplicates plugin instances in a flat config array using a first-wins strategy:

// @ts-check
import { defineConfig, reconcilePlugins } from '@poupe/eslint-config';
import someOtherConfig from 'some-other-eslint-config';

export default reconcilePlugins([
  ...someOtherConfig,
  ...defineConfig(),
]);

Poupe UI Recommended Rules

In addition to the rules from included plugins, this configuration adds these custom rules:

TypeScript Rules

  • Enforces explicit return types on exported functions
  • Requires consistent type imports (import type)
  • Disables @ts- comment directives

Vue.js Rules

  • Enforces multi-word component names
  • Requires defineEmits and defineProps type declarations
  • Ensures proper v-model usage patterns

General JavaScript Rules

  • Enforces camelCase naming convention
  • Allows i, j, k as loop counters and array indices
  • Requires explicit radix in parseInt
  • Prevents console statements in production code

Stylistic Rules

  • Single quotes for strings
  • Semicolons required
  • 1tbs (one true brace style)
  • 2-space indentation for web files
  • 80-character line limit for Markdown (tables exempt)

Migration Guide

From Legacy ESLint Config

If you're migrating from a legacy .eslintrc configuration:

  1. Remove old config files: Delete .eslintrc, .eslintrc.js, .eslintrc.json, etc.

  2. Update dependencies:

    pnpm remove eslint-config-* eslint-plugin-*
    pnpm install -D eslint @eslint/js typescript @poupe/eslint-config
  3. Create new config: Add eslint.config.mjs as shown in Getting Started

  4. Update scripts: ESLint automatically finds eslint.config.mjs

    {
      "scripts": {
        "lint": "eslint --fix .",
        "lint:check": "eslint ."
      }
    }
  5. Handle breaking changes:

    • Some rules have been renamed or moved to different plugins
    • The flat config uses different property names (files instead of overrides)
    • Plugin names are now used as object keys instead of strings

Examples

The examples/ directory contains working examples demonstrating how to use this ESLint configuration in different scenarios:

Running Examples

This project uses pnpm workspaces. You can run commands on all examples:

# Install dependencies for all workspaces
pnpm install

# Check all examples without fixing
pnpm -r --filter "./examples/*" lint:check

# Lint and fix all examples
pnpm -r --filter "./examples/*" lint

# Run a specific example
pnpm --filter "playground-standard" lint

Troubleshooting

Common Issues

"Cannot find module '@poupe/eslint-config'"

Ensure you've installed the package and are using the correct import path:

pnpm install -D @poupe/eslint-config

"Plugin conflict" errors with Nuxt

For Nuxt applications, use withPoupe from the root entry point:

  • Nuxt apps: withPoupe(withNuxt())
  • Nuxt modules: withPoupe(createConfigForNuxt(...))

CSS rules applying to JavaScript files

This should not happen with the default configuration. If it does, ensure you're using the latest version and report an issue.

"Unknown rule" warnings

These warnings help the CSS filtering system learn about new rules. They're informational and don't affect functionality.

Debugging

To debug ESLint configuration issues:

# Show resolved configuration for a specific file
eslint --print-config path/to/file.js

# Verbose per-file linting trace
env DEBUG=eslint:linter pnpm lint:check

# Debug config resolution
env DEBUG=eslint:eslint pnpm lint

Development

For AI assistants working with this codebase, refer to AGENTS.md for detailed guidance and conventions.

Project Structure

src/
├── configs/        # Individual ESLint rule configurations
├── core/           # Core utilities and type definitions
├── config.ts       # Main configuration builder
├── configs.ts      # Configuration presets
└── index.ts        # Main entry point

Contributing

  1. Make changes to configuration files in src/configs/
  2. Run pnpm build to compile the package
  3. Test with pnpm lint (self-linting)
  4. Test in examples: pnpm -r --filter "./examples/*" lint

License

MIT