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-fractal

v1.0.0

Published

ESLint plugin that enforces the Fractal React application structure: component import boundaries and at most one detected top-level React component per file.

Downloads

227

Readme

eslint-plugin-fractal

ESLint plugin that enforces the Fractal React application structure.

Two rules keep the component tree honest:

| Rule | What it enforces | | ------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | fractal/component-imports | A component may import components only from the shared components directory (src/components by default) or from its own same‑named child folder (Dashboard.tsx./dashboard/). | | fractal/one-component-per-file | A file defines at most one detected top-level React component. |

And one opt-in rule for teams that want a single export convention:

| Rule | What it enforces | | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- | | fractal/component-export-style | A file's own component is exported consistently, either as a named export (default) or as a default export. Fixable. |

Together these produce the Fractal shape: one‑off components branch out from a single entry point, while multi‑use components live in src/components and may have their own shared sub‑component folders. Based on the Fractal app structure.

Install

npm install --save-dev eslint-plugin-fractal

Requires Node.js >=22.14 and ESLint 8.57, 9, or 10 using flat config.

Usage

Enable the recommended preset (turns both structural rules on as errors):

// eslint.config.js
import fractal from 'eslint-plugin-fractal';

export default [fractal.configs.recommended];

CommonJS flat configs receive the plugin directly, without a .default property:

// eslint.config.cjs
const fractal = require('eslint-plugin-fractal');

module.exports = [fractal.configs.recommended];

Or wire the rules up yourself, scoped to your components, with options:

// eslint.config.js
import fractal from 'eslint-plugin-fractal';

export default [
  {
    files: ['src/**/*.{jsx,tsx}'],
    plugins: { fractal },
    rules: {
      'fractal/component-imports': [
        'error',
        {
          sharedDir: 'src/components',
          aliases: { '@/': 'src/' },
        },
      ],
      'fractal/one-component-per-file': 'error',
    },
  },
];

fractal/component-export-style is not part of the recommended preset. Add it explicitly if you want one export convention enforced:

rules: {
  'fractal/component-export-style': ['error', { style: 'named' }],
}

The plugin does not configure a parser. Use a parser that understands JSX/TSX — for example typescript-eslint — or espree with languageOptions.parserOptions.ecmaFeatures.jsx = true.

component-imports options

| Option | Type | Default | Purpose | | ------------------------- | ----------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------ | | sharedDir | string | "src/components" | Shared component directory, resolved from rootDir unless absolute. | | rootDir | string | ESLint cwd | Project root for shared and root-relative imports; relative values resolve from the ESLint cwd. | | aliases | Record<string,string> | {} | Nonempty literal prefixes matched longest-first, e.g. { "@/": "src/" }. | | allowAncestorSharedDirs | boolean | false | Also allow importing from a same‑named folder (e.g. components) at any ancestor directory, not just sharedDir. |

TypeScript consumers can import ComponentImportsOption for the option object or ComponentImportsOptions for ESLint's options tuple from the package root.

component-export-style options

| Option | Type | Default | Purpose | | ------- | ---------------------- | --------- | ----------------------------------------------------------------- | | style | "named" \| "default" | "named" | Export style required for the component matching the file's name. |

TypeScript consumers can import ComponentExportStyleOption or ComponentExportStyleOptions from the package root.

The rule is fixable, but --fix rewrites only the declaring file and never the files importing it. See the rule docs for the cases where a fix is deliberately skipped.

See the per‑rule docs for examples and the heuristics/limitations that apply. component-imports checks static ES import declarations; re-exports, dynamic imports, and CommonJS require() calls are outside its scope.

Monorepos

Use one flat-config block per package when packages have independent Fractal roots. Relative rootDir values resolve from the ESLint working directory:

{
  files: ['packages/app/src/**/*.{jsx,tsx}'],
  plugins: { fractal },
  rules: {
    'fractal/component-imports': ['error', {
      rootDir: 'packages/app',
      sharedDir: 'src/components',
      aliases: { '@app/': 'src/' },
    }],
    'fractal/one-component-per-file': 'error',
  },
}

Versioning

This package follows semantic versioning, interpreted the way ESLint interprets it for linting tools:

| Change | Release | | ------------------------------------------------------------------------------------------------ | ------- | | A fix that makes a rule report fewer problems | patch | | A new rule, a new option, or a change that can report new problems | minor | | Removing a rule or option, changing a default, or dropping a supported Node.js or ESLint version | major |

A minor release can therefore surface lint errors that a previous version did not report. Pin the version if your build treats new lint errors as failures.

New rules are added outside fractal/recommended when they encode a style preference rather than the Fractal structure, so extending recommended does not start reporting a convention you have not opted into.

Development

See CONTRIBUTING.md. In short:

npm ci
npm run check   # typecheck + lint + format:check + tests with coverage
npm run verify:package   # ESM + CJS + types + packed-file validation

Releasing

Releases are automated with semantic-release: merging Conventional Commits to main determines the next version, publishes to npm, and creates a GitHub release. Publishing uses npm trusted publishing through GitHub Actions; no npm token is stored in the repository. See MAINTAINING.md for one-time configuration and release verification. GitHub Releases are the canonical release notes.

License

MIT © Lauri Lavanti