oxc-project/oxc · warning · OxcDiagnostic

Prefer String#endsWith over a regex with a dollar sign.

Error message

Prefer String#endsWith over a regex with a dollar sign.

What it means

This is the `endsWith` diagnostic of oxlint's `unicorn/prefer-string-starts-ends-with` rule. It reports `/suffix$/.test(str)` — a regex anchored at the end with a dollar sign — and recommends `String#endsWith` for the same performance and clarity reasons as the caret variant. The rule is deprecated in favor of the type-aware `typescript/prefer-string-starts-ends-with`.

Source

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

};
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.
    /// :::
    ///
    /// ### Why is this bad?
    ///
    /// Using `String#startsWith()` and `String#endsWith()` is more readable and performant as it does not need to parse a regex.
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Replace `/\.json$/.test(name)` with `name.endsWith('.json')`.
  2. Switch to `typescript/prefer-string-starts-ends-with` and disable the deprecated unicorn rule.
  3. Auto-fix with `oxlint --fix` and eyeball the produced string literal for correctly unescaped characters.
  4. Keep the regex if you rely on case-insensitive (`i`) matching — `endsWith` is case-sensitive, so add `.toLowerCase()` or keep the regex.

Example fix

// before
const isJson = /\.json$/.test(filename);

// after
const isJson = filename.endsWith('.json');
Defensive patterns

Strategy: validation

Validate before calling

// Intent-revealing suffix checks
if (filename.endsWith('.json')) { /* ... */ }
// CI: npx oxlint --deny-warn unicorn/prefer-string-starts-ends-with src/

Prevention

When it happens

Trigger: A `.test()` call on a regex literal ending in `$` with only literal terms before it (boundary assertions recognized via `BoundaryAssertionKind::End`/`WordBoundary` handling in the rule's term walk); multiline (`m`) flags and trailing metacharacters disqualify the match. A fixer can rewrite to `str.endsWith('suffix')`.

Common situations: Extension/suffix checks like `/\.json$/.test(filename)`; the escaped dot is fine because `.` inside the class of literal terms is unescaped by the fixer. Same migration pressure to the typescript variant applies.

Related errors


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