{"record":{"id":"28eca0e33f107320","repo":"oxc-project/oxc","slug":"a-constructor-name-should-not-start-with-a-lowerca","errorCode":null,"errorMessage":"A constructor name should not start with a lowercase letter.","messagePattern":"A constructor name should not start with a lowercase letter\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/eslint/new_cap.rs","lineNumber":40,"sourceCode":"    let msg = if *cap == GetCapResult::Lower {\n        \"A constructor name should not start with a lowercase letter.\"\n    } else {\n        \"A function with a name starting with an uppercase letter should only be used as a constructor.\"\n    };\n\n    let label = if *cap == GetCapResult::Lower {\n        \"This should be uppercase\"\n    } else {\n        \"This should be called with `new`\"\n    };\n\n    let help = if *cap == GetCapResult::Lower {\n        \"Capitalize the first letter of the constructor name, or add it to the exceptions list if it should not be capitalized.\"\n    } else {\n        \"Use the new operator when calling this function, or add it to the exceptions list if it should not be called with new.\"\n    };\n\n    OxcDiagnostic::warn(msg).with_help(help).with_label(span.label(label))\n}\n\n#[derive(Debug, Default, Clone, Deserialize)]\npub struct NewCap(Box<NewCapConfig>);\n\n#[derive(Debug, Clone, Deserialize, JsonSchema)]\n#[serde(rename_all = \"camelCase\", default, deny_unknown_fields)]\npub struct NewCapConfig {\n    /// `true` to require that all constructor names start with an uppercase letter, e.g. `new Person()`.\n    new_is_cap: bool,\n    /// `true` to require that all functions with names starting with an uppercase letter to be called with `new`.\n    cap_is_new: bool,\n    /// Exceptions to ignore for constructor names starting with an uppercase letter.\n    new_is_cap_exceptions: Vec<CompactStr>,\n    /// A regex pattern to match exceptions for constructor names starting with an uppercase letter.\n    #[serde(default, deserialize_with = \"deserialize_regex_option\")]\n    new_is_cap_exception_pattern: Option<Regex>,\n    /// Exceptions to ignore for functions with names starting with an uppercase letter.","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/oxc-project/oxc/blob/1f902a69625cd14e6d8dc58feca94da099d2d251/crates/oxc_linter/src/rules/eslint/new_cap.rs#L22-L58","documentation":"Reported by the `new-cap` rule when `newIsCap` is enabled (default true) and a `new` expression's callee is an identifier (or property, when `properties: true`) starting with a lowercase letter. The message is fixed ('A constructor name should not start with a lowercase letter.') while the label/help adapt: for the Lower case the label says 'This should be uppercase' (crates/oxc_linter/src/rules/eslint/new_cap.rs:31-43). A built-in exceptions list (`newIsCapExceptions`, seeded from caps_allowed_vec) whitelists known lowercase constructors.","triggerScenarios":"`const s = new person()`, `new myModule.Thing`-style lowercase property calls with `properties: true`, or lowercase factory constructors not in the exceptions list. Defaults: `newIsCap: true`, `capIsNew: true`, `properties: true` (crates/oxc_linter/src/rules/eslint/new_cap.rs:67-77).","commonSituations":"Calling `new` on third-party libraries whose constructors are lowercase (older libraries, some DSL builders); using lowercase class names in throwaway prototypes; the rule flagging dynamic property access paths; config migrations that dropped a previously maintained `newIsCapExceptions` list.","solutions":["Capitalize the constructor: `new Person()` — rename the class/function itself if you own it.","If the lowercase name is a third-party API you cannot change, add it to `newIsCapExceptions` (e.g. `[\"stream\", \"peer\"]`) or a `newIsCapExceptionPattern` regex in `.oxlintrc.json`.","If it is actually a factory function, drop the `new` (verify the implementation supports being called without `new`)."],"exampleFix":"// before\nconst emitter = new eventEmitter();\n\n// after\nconst emitter = new EventEmitter();","handlingStrategy":"validation","validationCode":"// CI: oxlint --rule new-cap src/\n// Register known lowercase third-party constructors up front:\n// { \"new-cap\": [{ \"newIsCapExceptions\": [\"myLib.builder\"], \"newIsCapExceptionPattern\": \"^[a-z]+\\\\$\" }] }","typeGuard":"// Convention guard (TypeScript): classes are PascalCase; a type predicate for callables you own:\nfunction isConstructor<T>(fn: new (...args: never[]) => T): true { return true; }","tryCatchPattern":null,"preventionTips":["Name constructors with an uppercase first letter at creation time; renaming later touches every call site.","Maintain newIsCapExceptions in config as the single place third-party lowercase constructors are acknowledged.","Prefer class syntax over function-constructor patterns in new code — classes make the constructor role obvious."],"tags":["eslint","oxlint","style","naming","constructor","new-cap"],"backgroundTag":"constructor-naming-convention","analyzedSha":"1f902a69625cd14e6d8dc58feca94da099d2d251","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}