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

@tnnquang/eslint

v2.0.4

Published

ESLint plugin with custom rules for TypeScript frameworks (React, Vue, Angular, NestJS, Next.js, Nuxt)

Downloads

14

Readme

@tnnquang/eslint

ESLint plugin with custom rules for TypeScript frameworks including React, Vue, Angular, NestJS, Next.js, and Nuxt.

Features

  • no-namespace-import: Prevent namespace imports, encourage named imports with autofix
  • no-arrow-components: Enforce function declarations over arrow functions for components
  • enforce-path-alias: Enforce usage of path aliases based on tsconfig/vite configuration

Installation

npm install --save-dev @tnnquang/eslint

Usage

Framework-Specific Configurations

Choose the configuration that matches your framework:

React/Next.js

{
  "extends": ["plugin:@tnnquang/eslint/react"]
}

Vue/Nuxt

{
  "extends": ["plugin:@tnnquang/eslint/vue"]
}

Angular

{
  "extends": ["plugin:@tnnquang/eslint/angular"]
}

NestJS

{
  "extends": ["plugin:@tnnquang/eslint/nestjs"]
}

General/Recommended

{
  "extends": ["plugin:@tnnquang/eslint/recommended"]
}

Strict Mode

{
  "extends": ["plugin:@tnnquang/eslint/strict"]
}

Manual Configuration

{
  "plugins": ["@tnnquang/eslint"],
  "rules": {
    "@tnnquang/eslint/no-arrow-components": "warn",
    "@tnnquang/eslint/no-namespace-import": "warn",
    "@tnnquang/eslint/enforce-path-alias": "warn"
  }
}

Each rule supports standard ESLint severity levels: "off", "warn", or "error".

Rules

@tnnquang/eslint/no-arrow-components

Enforces function declarations for React components and top-level functions instead of arrow functions.

Note: This rule is automatically disabled for Vue, Angular, and NestJS configurations as these frameworks use different component patterns.

❌ Incorrect

// React components should be function declarations
const MyComponent = () => {
  return <div>Hello</div>;
};

// Top-level utility functions should be function declarations const utilityFunction = (param) => { return param * 2; };


#### ✅ Correct

```javascript
// Function declaration for React components
function MyComponent() {
  return <div>Hello</div>;
}

// Function declaration for utility functions
function utilityFunction(param) {
  return param * 2;
}

// Arrow functions are allowed when wrapped in HOCs
const MyMemoizedComponent = memo(() => {
  return <div>Hello</div>;
});

const MyForwardRefComponent = forwardRef(() => {
  return <div>Hello</div>;
});

@tnnquang/eslint/no-namespace-import

Disallows using default imports as namespaces and encourages direct named imports. Works with any library, not just React!

Configuration Options

// .eslintrc.js
module.exports = {
  rules: {
    "@tnnquang/eslint/no-namespace-import": [
      "error",
      {
        // Only check specific libraries
        targetLibraries: ["react", "lodash", "redux"],

        // Allow some libraries to use namespace imports
        allowedLibraries: ["moment", "dayjs"],
      },
    ],
  },
};

❌ Incorrect

import React from "react";
import _ from "lodash";
import Redux from "redux";
import moment from "moment";

function MyComponent() {
  const [state, setState] = React.useState(0);
  const data = _.map([1, 2, 3], (x) => x * 2);
  const store = Redux.createStore(reducer);
  const date = moment.format("YYYY-MM-DD");

  return <div>{state}</div>;
}

✅ Correct (Auto-fixable)

import { useState } from "react";
import { map } from "lodash";
import { createStore } from "redux";
import moment from "moment"; // Allowed in config

function MyComponent() {
  const [state, setState] = useState(0);
  const data = map([1, 2, 3], (x) => x * 2);
  const store = createStore(reducer);
  const date = moment.format("YYYY-MM-DD");

  return <div>{state}</div>;
}

Auto-fix Capability

This rule automatically fixes violations when you run:

eslint --fix your-file.js

@tnnquang/eslint/enforce-path-alias

Enforces usage of path aliases for imports based on TypeScript or Vite configuration.

Configuration Options

// .eslintrc.js
module.exports = {
  rules: {
    "@tnnquang/eslint/enforce-path-alias": [
      "warn",
      {
        // Mode: "all" or "direct-children" (default)
        mode: "direct-children",
        
        // Config file to read (default: tsconfig.json)
        configFile: "tsconfig.json",
        
        // Base URL (auto-detected from config)
        baseUrl: "./src",
        
        // Folders to exclude from alias enforcement
        exclude: ["test", "spec"],
        
        // Manual path configuration (overrides auto-detection)
        paths: {
          "@/*": ["./src/*"],
          "@components/*": ["./src/components/*"],
          "@utils/*": ["./src/utils/*"]
        }
      }
    ]
  }
};

❌ Incorrect

// In src/components/Button.tsx
import { validateInput } from "../utils/validation";
import { API_URL } from "../config/constants";

✅ Correct (Auto-fixable)

// In src/components/Button.tsx
import { validateInput } from "@/utils/validation";
import { API_URL } from "@/config/constants";

Framework Support

This rule automatically detects configuration from:

  • TypeScript: tsconfig.json paths mapping
  • Vite: vite.config.js/ts alias configuration
  • Next.js: Next.js project structure
  • Nuxt: Nuxt project structure
  • Angular: Angular workspace configuration

TypeScript Configuration

For TypeScript projects, the plugin automatically detects .ts and .tsx files and applies enhanced rules:

// .eslintrc.js
module.exports = {
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint", "@tnnquang/eslint"],
  extends: [
    "@typescript-eslint/recommended",
    "plugin:@tnnquang/eslint/react", // or your framework config
  ],
  rules: {
    // Enhanced TypeScript support
    "@tnnquang/eslint/no-arrow-components": [
      "warn",
      {
        allowArrowFunctions: false,
        checkTypeScript: true, // Enable TypeScript-specific checks
      },
    ],
    "@tnnquang/eslint/no-namespace-import": [
      "warn", 
      {
        checkTypeScriptTypes: true, // Check type imports
        allowTypeNamespaces: false, // Disallow type namespaces
        targetLibraries: ["react", "@types/node"],
      },
    ],
    "@tnnquang/eslint/enforce-path-alias": [
      "warn",
      {
        supportedExtensions: [".ts", ".tsx", ".js", ".jsx"],
        includeDeclarationFiles: false, // Skip .d.ts files
      },
    ],
  },
};

Configuration Examples

For React Projects

// .eslintrc.js
module.exports = {
  extends: ["plugin:@tnnquang/eslint/recommended"],
  rules: {
    // Customize if needed
    "@tnnquang/eslint/no-arrow-components": "warn",
  },
};

For General JavaScript Projects

// .eslintrc.js
module.exports = {
  plugins: ["@tnnquang/eslint"],
  rules: {
    "@tnnquang/eslint/no-namespace-import": [
      "error",
      {
        targetLibraries: ["lodash", "ramda", "rxjs"],
        allowedLibraries: ["moment", "dayjs"],
      },
    ],
  },
};

With TypeScript

// .eslintrc.js or eslint.config.js
module.exports = {
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint", "@tnnquang/eslint"],
  extends: [
    "plugin:@typescript-eslint/recommended",
    "plugin:@tnnquang/eslint/recommended",
  ],
};

Why These Rules?

Function Declarations Benefits

  • Hoisting: Better code organization flexibility
  • Debugging: Clearer stack traces
  • Consistency: Uniform coding style
  • Performance: Minor performance benefits

Named Imports Benefits

  • Tree Shaking: Better dead code elimination
  • Bundle Size: Smaller production bundles
  • Clarity: Explicit dependency tracking
  • Performance: Faster bundling and optimization

Supported Libraries

The no-namespace-import rule works with any JavaScript library:

  • ✅ React (React.useStateuseState)
  • ✅ Lodash (_.mapmap)
  • ✅ Redux (Redux.createStorecreateStore)
  • ✅ RxJS (Rx.ObservableObservable)
  • ✅ Ramda (R.pipepipe)
  • ✅ Any other library with named exports

License

MIT

Troubleshooting

ESLint Configuration Conflicts

If you encounter ESLint configuration conflicts:

  1. Make sure you don't have conflicting configs: This plugin doesn't include any .eslintrc.js files that could interfere with your project.

  2. Plugin loading issues: Ensure the plugin is properly installed:

    npm ls @tnnquang/eslint
  3. Rule conflicts: If you have other ESLint plugins with similar rules, you can disable specific rules:

    {
      "rules": {
        "@tnnquang/eslint/no-arrow-components": "off"
      }
    }
  4. TypeScript integration: For TypeScript projects, make sure you have proper parser configuration:

    {
      "parser": "@typescript-eslint/parser",
      "plugins": ["@typescript-eslint", "@tnnquang/eslint"]
    }

Contributing

Issues and pull requests are welcome!

Repository: https://github.com/tnnquang/eslint-plugin

Changelog

v2.0.1

  • Fixed Configuration Conflicts: Removed internal ESLint config files from npm package to prevent conflicts with user configurations
  • Added .npmignore to exclude development files
  • Added troubleshooting section to README

v2.0.0

  • Enhanced TypeScript Support: All rules now have improved TypeScript detection and support
  • Added TypeScript type definitions (lib/index.d.ts)
  • Enhanced no-arrow-components with TypeScript component detection and configurable options
  • Enhanced no-namespace-import with TypeScript type import support and type namespace options
  • Enhanced enforce-path-alias with TypeScript file extension support and declaration file handling
  • Added comprehensive TypeScript configuration examples
  • Added support for .ts, .tsx, .vue, .svelte file extensions
  • Improved auto-detection of project structure for TypeScript projects

Author

Tran Ngoc Nhat Quang