{"record":{"id":"1ee842307af10910","repo":"oxc-project/oxc","slug":"file-has-too-many-classes-total-maximum-allow","errorCode":null,"errorMessage":"File has too many classes ({total}). Maximum allowed is {max}","messagePattern":"File has too many classes \\((.+?)\\)\\. Maximum allowed is (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/max_classes_per_file.rs","lineNumber":13,"sourceCode":"use oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\nuse schemars::JsonSchema;\nuse serde::Deserialize;\n\nuse crate::{\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn max_classes_per_file_diagnostic(total: u32, max: u32, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"File has too many classes ({total}). Maximum allowed is {max}\"))\n        .with_help(\"Reduce the number of classes in this file\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct MaxClassesPerFile(Box<MaxClassesPerFileConfig>);\n\n#[derive(Debug, Clone, JsonSchema, Deserialize)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct MaxClassesPerFileConfig {\n    /// The maximum number of classes allowed per file.\n    pub max: u32,\n    /// Whether to ignore class expressions when counting classes.\n    pub ignore_expressions: bool,\n}\n\nimpl std::ops::Deref for MaxClassesPerFile {\n    type Target = MaxClassesPerFileConfig;","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/max_classes_per_file.rs#L1-L31","documentation":"Diagnostic of the `max-classes-per-file` rule. It counts class declarations (and by default class expressions too) in a single file and reports when the count exceeds the configured maximum, with default `max: 1` (crates/oxc_linter/src/rules/eslint/max_classes_per_file.rs:38-41). The span labels the class that pushed the file over the limit. The intent is one-responsibility-per-file cohesion.","triggerScenarios":"A file containing two or more classes with default config: `class A {} class B {}` triggers immediately. Any `class ... {}` declaration increments the counter; class expressions (`const A = class {}`) also count unless `ignoreExpressions: true` is set. Config `{ \"max-classes-per-file\": [\"error\", { \"max\": 3, \"ignoreExpressions\": true }] }` changes the thresholds.","commonSituations":"Bundling helper/mock classes or test doubles into one test file; exporting multiple small value-object classes from a barrel-ish module; migrating from ESLint where the rule was enabled with default max 1; refactoring that temporarily introduces an extra class during extraction.","solutions":["Split the file so each class lives in its own module (matches the rule's intent and default max of 1).","If multiple related classes legitimately belong together (e.g. AST node types, DTOs), raise the limit: `{ \"max\": 5 }`.","Set `ignoreExpressions: true` when class expressions are used for anonymous/one-off implementations such as HOCs or dynamic classes."],"exampleFix":"// before (file: shapes.js)\nclass Circle { /* ... */ }\nclass Square { /* ... */ }\n\n// after: shapes/circle.js -> export class Circle {...}\n//        shapes/square.js -> export class Square {...}","handlingStrategy":"validation","validationCode":"// CI gate before merge:\n// oxlint --rule max-classes-per-file='{\"max\":1}' src/\n// For mixed modules: {\"max\": 3, \"ignoreExpressions\": true}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to one class per file when scaffolding; new files are cheap, splits later are not.","Use class expressions for anonymous one-offs if the team counts declarations only (ignoreExpressions).","Watch test files that inline mock classes — configure per-glob overrides instead of weakening the global limit."],"tags":["eslint","oxlint","style","file-structure","classes"],"backgroundTag":"code-complexity-limits","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}