{"record":{"id":"c56aac7ccc25b074","repo":"oxc-project/oxc","slug":"prefer-good-method-over-bad-method","errorCode":null,"errorMessage":"Prefer `{good_method}` over `{bad_method}`","messagePattern":"Prefer `(.+?)` over `(.+?)`","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs","lineNumber":9,"sourceCode":"use oxc_ast::AstKind;\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\n\nuse crate::{AstNode, context::LintContext, rule::Rule};\n\nfn prefer_code_point_diagnostic(span: Span, good_method: &str, bad_method: &str) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(\"Prefer `{good_method}` over `{bad_method}`\"))\n        .with_help(format!(\"Unicode is better supported in `{good_method}` than `{bad_method}`\"))\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferCodePoint;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prefer usage of `String#codePointAt` over `String#charCodeAt`.\n    /// Prefer usage of `String.fromCodePoint` over `String.fromCharCode`.\n    ///\n    /// ### Why is this bad?\n    ///\n    /// Unicode is better supported in [`String#codePointAt()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt) and [`String.fromCodePoint()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint).\n    ///\n    /// [Difference between `String.fromCodePoint()` and `String.fromCharCode()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint#compared_to_fromcharcode)","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/prefer_code_point.rs#L1-L27","documentation":"Lint diagnostic from oxlint's `unicorn/prefer-code-point` rule. JavaScript strings are UTF-16, so `charCodeAt(i)`/`fromCharCode(n)` operate on 16-bit code units and mis-handle characters outside the BMP (emoji, CJK extensions) that are stored as surrogate pairs. `codePointAt(i)`/`fromCodePoint(n)` operate on Unicode code points. The rule flags the code-unit APIs; `{good_method}`/`{bad_method}` interpolate as `codePointAt`/`charCodeAt` or `fromCodePoint`/`fromCharCode`.","triggerScenarios":"Calls to `str.charCodeAt(index)` or `String.fromCharCode(num[, ...nums])` anywhere in scanned code — member call on `charCodeAt`, or static `fromCharCode` call. Reported during oxlint runs when the rule is enabled (unicorn category, style/pedantic group).","commonSituations":"String-indexing utilities (capitalizers, cipher/hash ports, char walkers) written with charCodeAt. Breaks visibly once input contains emoji or rare CJK characters — `charCodeAt` yields surrogate halves, producing mojibake. Surfaces in bulk when the unicorn category is turned on, including in vendored/ported code.","solutions":["Replace `str.charCodeAt(i)` with `str.codePointAt(i)` and `String.fromCharCode(n)` with `String.fromCodePoint(n)`.","Audit iteration: use `for (const ch of str)` (code points) instead of index loops when converting.","If code-unit semantics are intentional (UTF-16 encoding, Base64, hash functions like FNV/djb2 over code units), suppress with `// oxlint-disable-next-line unicorn/prefer-code-point` and state why — changing those breaks the algorithm.","Disable the rule for codec/hash-heavy files via `.oxlintrc.json` overrides if most calls are intentionally code-unit based."],"exampleFix":"// before\nconst first = str.charCodeAt(0);\nconst ch = String.fromCharCode(0x1F600);\n\n// after\nconst first = str.codePointAt(0);\nconst ch = String.fromCodePoint(0x1F600); // U+1F600 emoji","handlingStrategy":"validation","validationCode":"// oxlint --filter unicorn/prefer-code-point src/\n// CI gate: oxlint --deny-warnings src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Default to `codePointAt`/`fromCodePoint` and `for...of` iteration for user-facing text.","Keep `charCodeAt`/`fromCharCode` only in UTF-16/codec/hash code with an inline suppression explaining code-unit semantics.","Test string utilities with emoji and astral-plane characters ('\\u{1F600}') to catch surrogate-pair bugs the rule warns about."],"tags":["oxlint","unicorn","unicode","strings","es2015","i18n"],"backgroundTag":"lint-rule-violation","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"}