oxc-project/oxc · warning · OxcDiagnostic

Prefer String#startsWith over a regex with a caret.

Error message

Prefer String#startsWith over a regex with a caret.

What it means

This is the `startsWith` diagnostic of oxlint's `unicorn/prefer-string-starts-ends-with` rule. It reports `/^prefix/.test(str)` — a regex anchored at the start with a caret — and recommends `String#startsWith`, which is faster (no regex engine) and communicates intent. Note the rule's doc marks it deprecated in favor of the type-aware `typescript/prefer-string-starts-ends-with` rule.

Source

Thrown at crates/oxc_linter/src/rules/unicorn/prefer_string_starts_ends_with.rs:18

use oxc_ast::{
    AstKind,
    ast::{CallExpression, Expression, MemberExpression, RegExpFlags, RegExpLiteral},
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_regular_expression::ast::{BoundaryAssertionKind, Term};
use oxc_span::{GetSpan, Span};

use crate::{
    AstNode,
    context::LintContext,
    fixer::{RuleFix, RuleFixer},
    rule::Rule,
};

fn starts_with(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Prefer String#startsWith over a regex with a caret.").with_label(span)
}

fn ends_with(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Prefer String#endsWith over a regex with a dollar sign.").with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct PreferStringStartsEndsWith;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Prefer [`String#startsWith()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) and [`String#endsWith()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith) over using a regex with `/^foo/` or `/foo$/`.
    ///
    /// ::: warning
    /// This rule is deprecated. Prefer the type-aware [`typescript/prefer-string-starts-ends-with`](https://oxc.rs/docs/guide/usage/linter/rules/typescript/prefer-string-starts-ends-with.html) rule instead.
    /// :::
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace `/^prefix/.test(str)` with `str.startsWith('prefix')`.
  2. Migrate to the replacement rule `typescript/prefer-string-starts-ends-with` (requires type-aware linting) and turn the deprecated unicorn rule off.
  3. Run `oxlint --fix` to auto-convert safe cases.
  4. If the regex has anchors plus other constructs (character classes, `m` flag, lookahead), leave it — the rule correctly does not fire or the fix would change meaning.

Example fix

// before
if (/^https:/.test(url)) { ... }

// after
if (url.startsWith('https:')) { ... }
Defensive patterns

Strategy: validation

Validate before calling

// Intent-revealing prefix checks
if (url.startsWith('https:')) { /* ... */ }
// CI: npx oxlint --deny-warn unicorn/prefer-string-starts-ends-with src/

Prevention

When it happens

Trigger: A `.test()` call whose argument is a regex literal beginning with `^` followed by only literal terms (boundary assertions parsed via `oxc_regular_expression::ast::BoundaryAssertionKind` / `Term`); the regex must be anchored-at-start only, non-inverted, and free of metacharacters that would change `startsWith` equivalence. A fixer (`RuleFix`/`RuleFixer`) can rewrite it to `str.startsWith('prefix')`.

Common situations: Prefix checks written by developers who reach for regex out of habit, e.g. `/^https/.test(url)`; teams migrating configs see the deprecation notice and are steered toward the TypeScript variant, which needs type information to know the receiver is a string.

Related errors


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