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

eslint-plugin-explicit-use-directives

v0.0.3

Published

ESLint plugin to enforce explicit 'use' directives like "use client" at the top of JSX and TSX files.

Readme

eslint-plugin-explicit-use-directives

Some frameworks use "use" directives at the top of files to change how the contents of the file should be run or rendered. For example, in the Next.js app router, all components are Server Components by default unless you add "use client" as the first line of the file. This can violate the principle of least surprise, because a component might render only on the server when you expect it to also run in the browser.

This plugin fixes that by making these directives explicit. It ensures that all (.jsx and .tsx) files start with either "use server" or "use client". You can also choose whichever directive you prefer. The plugin also autofixes missing directives automatically. See the configuration options for for further customizability.

Getting started

npm install --save-dev eslint-plugin-explicit-use-directives

eslint.config.js

import explicitUse from "eslint-plugin-explicit-use-directives";
export default [
  // Prefer "use server" by default:
  explicitUse.configs["prefer-use-server"],

  // Or prefer "use client" by default:
  // explicitUse.configs["prefer-use-client"],
];

Examples

Insert "use server" and enforce an empty line (always)

// Config snippet
import explicitUse from "eslint-plugin-explicit-use-directives";

export default [
  {
    plugins: { "explicit-use-directives": explicitUse },
    rules: {
      "explicit-use-directives/require-use-directive-first": [
        "error",
        { directive: "use server" },
      ],
      "explicit-use-directives/empty-line-after-use-directive": [
        "error",
        "always",
      ],
    },
  },
];

Before

export async function getUserData(id) {
  const res = await fetch(`https://api.example.com/users/${id}`);
  return res.json();
}

After (autofixed)

"use server";

export async function getUserData(id) {
  const res = await fetch(`https://api.example.com/users/${id}`);
  return res.json();
}

Insert "use client" and enforce no empty line (never)

// Config snippet
import explicitUse from "eslint-plugin-explicit-use-directives";

export default [
  {
    plugins: { "explicit-use-directives": explicitUse },
    rules: {
      "explicit-use-directives/require-use-directive-first": [
        "error",
        { directive: "use client" },
      ],
      "explicit-use-directives/empty-line-after-use-directive": [
        "error",
        "never",
      ],
    },
  },
];

Before

import { useState, useEffect } from "react";

export function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Counter mounted");
  }, []);

  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

After (autofixed)

"use client";
import { useState, useEffect } from "react";

export function Counter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log("Counter mounted");
  }, []);

  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

Rules

explicit-use-directives/require-use-directive-first Ensures a top-of-file use ... directive exists and inserts it automatically if missing.

Options (require-use-directive-first)

| Option | Type | Description | Default | Example | | ---------------------- | -------- | ------------------------------------------------------------------------------------ | ---------------- | ----------------------------------------------------------------------------------------------- | | directive | string | The directive to insert when missing. Required. | - | directive: "use server" inserts "use server" at the top of missing files. | | ignore | string[] | Glob-like patterns matched against the full POSIX path. Use **/ to match anywhere. | [] | ignore: ["**/pages/**", "**/tests/**"] skips those folders. | | ignoredDirectives | string[] | Directives that should not satisfy the rule (for example, "use strict"). | [] | ignoredDirectives: ["use strict"] still inserts "use client" even if "use strict" exists. | | requireExact | boolean | Only pass when the exact configured directive exists. | false | requireExact: true with directive: "use client" fails if the file has "use server". | | requireOneOf | string[] | Accept any one of these exact directives. Takes precedence over requireExact. | [] | requireOneOf: ["use client", "use server"] passes if the file has either. | | extensions | string[] | File extensions (without dot) to check. Replaces defaults when provided. | ["jsx", "tsx"] | extensions: ["js", "ts", "tsx"] also checks .js and .ts files. | | includeNodeModules | boolean | Include files inside node_modules. | false | includeNodeModules: true runs the rule even in node_modules. |

explicit-use-directives/empty-line-after-use-directive Enforces whether there should be a blank line after the last top-of-file use ... directive. Autofixable.

Options (empty-line-after-use-directive)

| Option | Type | Description | Default | Example | | ------ | ------ | ---------------------------------------------------- | -------- | -------------------------------------------- | | value | string | Layout mode for blank line after the last directive. | always | ["error", "never"] removes the blank line. |