Skip to content

sbougerel/eslint-plugin-next-use-client-boundary

Repository files navigation

eslint-plugin-next-use-client-boundary

A Typescript ESLint plugin for Next.js projects that enforces serializable props for exported components in 'use client' modules. This rule aims to emulate the Next.js Typescript server rule reference implementation here.

Examples

Invalid

'use client';

// ❌ Error: Functions are not serializable
export function Button({ onClick }: { onClick: () => void }) {
  return <button onClick={onClick}>Click me</button>;
}

// ❌ Error: Class instances are not serializable
export function UserCard({ user }: { user: User }) {
  return <div>{user.name}</div>;
}

Valid

'use client';

// ✅ Server Actions are allowed (name ends with "Action")
export function Form({ submitAction }: { submitAction: () => Promise<void> }) {
  return <form action={submitAction}>...</form>;
}

// ✅ Primitive types and plain objects are serializable
export function UserCard({ name, age }: { name: string; age: number }) {
  return <div>{name} is {age} years old</div>;
}

// ✅ Arrays and nested serializable types are allowed
export function List({ items }: { items: Array<{ id: string; title: string }> }) {
  return <ul>{items.map(item => <li key={item.id}>{item.title}</li>)}</ul>;
}

Installation

npm install --save-dev @sbougerel/eslint-plugin-next-use-client-boundary
# or
yarn add --dev @sbougerel/eslint-plugin-next-use-client-boundary
# or
pnpm add --save-dev @sbougerel/eslint-plugin-next-use-client-boundary

Usage

This plugin requires TypeScript type information to function properly. Add to your ESLint configuration:

// eslint.config.mjs
import nextUseClientBoundary from '@sbougerel/eslint-plugin-next-use-client-boundary';
import eslint from '@eslint/js';
import { defineConfig } from 'eslint/config';
import tseslint from 'typescript-eslint';

export default defineConfig(
  eslint.configs.recommended,
  tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  nextUseClientBoundary.configs.recommended,
);

Note: This plugin only provides a recommended configuration because the rule requires TypeScript's type checker to analyze prop types. See the TypeScript ESLint typed linting documentation for more information on setting up type-aware linting.

Rules

💼 Configurations enabled in.
✅ Set in the recommended configuration.

Name                       Description 💼
props-must-be-serializable Enforce serializable props in Next.js "use client" components

props-must-be-serializable

Enforces serializable props for exported components in 'use client' modules.

The types that are not supported in React 'use client' reference on serializable types will fail the rule:

  • Functions that are not exported from client-marked modules or marked with 'use server'
  • Classes
  • Objects that are instances of any class (other than the built-ins mentioned) or objects with a null prototype
  • Symbols not registered globally, ex. Symbol('my new symbol')

Next.js' reference implementation for this plugin has some differences:

  • If a function's name is action or ends in Action, the rule will pass,
  • If a function's name is reset and the file name is an error file or a global error file, the rule will pass,
  • Symbols that are not registered globally will not fail the rule.

The rule automatically skips test files (files with names containing .test. or .spec.).

Known Limitations

  • Nested scope exports: The rule only searches for variable declarations in the top-level program scope. Variables declared in nested scopes (like within block statements) and then exported are not validated. This pattern is rare in practice:

    'use client';
    {
      const Component = (props: Props) => {}; // Not validated
      export { Component };
    }

Requirements

  • ESLint 9.0.0 or higher
  • Next.js 14.0.0 or higher

License

MIT

Development

Running Tests

After cloning the repository and installing dependencies:

npm install
npm test

The tests verify that the rule correctly identifies valid and invalid usage of the 'use client' directive.

References

About

A Typescript ESLint plugin for Next.js projects that enforces serializable props for exported components in `'use client'` modules.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors