oxc-project/oxc · warning · OxcDiagnostic

A function with a name starting with an uppercase letter sho

Error message

A function with a name starting with an uppercase letter should only be used as a constructor.

What it means

The inverse branch of `new-cap`: with `capIsNew` enabled (default true), calling a function whose name starts with an uppercase letter without `new` produces this diagnostic ('A function with a name starting with an uppercase letter should only be used as a constructor.'). The label for this branch reads 'This should be called with `new`' and the help suggests using `new` or adding an exception (crates/oxc_linter/src/rules/eslint/new_cap.rs:31-43). It enforces the widespread convention that capitalized identifiers are constructors.

Source

Thrown at crates/oxc_linter/src/rules/eslint/new_cap.rs:40

    let msg = if *cap == GetCapResult::Lower {
        "A constructor name should not start with a lowercase letter."
    } else {
        "A function with a name starting with an uppercase letter should only be used as a constructor."
    };

    let label = if *cap == GetCapResult::Lower {
        "This should be uppercase"
    } else {
        "This should be called with `new`"
    };

    let help = if *cap == GetCapResult::Lower {
        "Capitalize the first letter of the constructor name, or add it to the exceptions list if it should not be capitalized."
    } else {
        "Use the new operator when calling this function, or add it to the exceptions list if it should not be called with new."
    };

    OxcDiagnostic::warn(msg).with_help(help).with_label(span.label(label))
}

#[derive(Debug, Default, Clone, Deserialize)]
pub struct NewCap(Box<NewCapConfig>);

#[derive(Debug, Clone, Deserialize, JsonSchema)]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct NewCapConfig {
    /// `true` to require that all constructor names start with an uppercase letter, e.g. `new Person()`.
    new_is_cap: bool,
    /// `true` to require that all functions with names starting with an uppercase letter to be called with `new`.
    cap_is_new: bool,
    /// Exceptions to ignore for constructor names starting with an uppercase letter.
    new_is_cap_exceptions: Vec<CompactStr>,
    /// A regex pattern to match exceptions for constructor names starting with an uppercase letter.
    #[serde(default, deserialize_with = "deserialize_regex_option")]
    new_is_cap_exception_pattern: Option<Regex>,
    /// Exceptions to ignore for functions with names starting with an uppercase letter.

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Add `new` if the target genuinely is a constructor: `const p = new Person();`.
  2. If the capitalized identifier is a factory or namespace, add it to `capIsNewExceptions` or set `capIsNewExceptionPattern` (e.g. `"^[A-Z][a-z]+\\.$"` for namespaces) in the rule configuration.
  3. Rename the factory to lowercase (`Client()` → `createClient()`) so the convention matches the usage.

Example fix

// before
const client = ApiClient(base_url);

// after
const client = new ApiClient(base_url);
// or, if it is a factory: const client = createApiClient(base_url);
Defensive patterns

Strategy: validation

Validate before calling

// CI: oxlint --rule new-cap src/
// Before calling a capitalized import, check whether it is a class/constructor:
// .oxlintrc.json -> "capIsNewExceptions": ["Client", "Utils"] or exceptionPattern for namespaces.

Type guard

// TypeScript narrowing by construct-signature presence:
type Constructor<T> = new (...args: any[]) => T;
function isConstructor<T>(value: unknown): value is Constructor<T> {
  return typeof value === 'function' && /^([A-Z])/.test(value.name);
}

Prevention

When it happens

Trigger: `const p = Person();`, `Db.connect()` where `Db` is a capitalized function invoked as a normal call, `SomeLibrary.method()` with `properties: true` — any call expression whose callee begins with a capital letter and the target is a function, unless listed in `capIsNewExceptions` or matched by `capIsNewExceptionPattern` (both default empty).

Common situations: Libraries whose capitalized exports are plain factory functions (e.g. older jQuery-era APIs, `fetch`-wrapper libraries named `Client`); namespaced singletons like `Utils.method()`; refactoring a class into a factory and forgetting to lowercase the name; enabling `new-cap` after adding such a dependency.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/629e66a17ae218dd. Report an issue: GitHub.