JavaScript String charCodeAt() Method

Beginner
⏱️ 10 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Instance method

What You’ll Learn

String.prototype.charCodeAt() returns an integer between 0 and 65535 for the UTF-16 code unit at a zero-based index (same API as MDN String.prototype.charCodeAt()). Learn out-of-range NaN, how it differs from codePointAt(), the link to fromCharCode(), five examples, and try-it labs.

01

Kind

Instance method

02

Returns

0–65535 or NaN

03

Indexes

UTF-16 units

04

vs codePointAt

Full Unicode

05

Mutates?

No

06

Baseline

Widely available

Introduction

charAt() gives you the character as text. charCodeAt() gives you the same position as a number — the UTF-16 code unit stored at that index.

For everyday ASCII letters this number is the familiar Unicode value ("A"65, "q"113. For many emoji and rare characters, JavaScript stores two code units (a surrogate pair), so charCodeAt() may return only half of the character. Prefer codePointAt() when you need the full Unicode value.

💡
Beginner tip

Out of range, charCodeAt() returns NaN — not 0 and not an empty string. Check with Number.isNaN(...).

This page is part of JavaScript String Methods. Related topics include charAt() and at().

Understanding the charCodeAt() Method

charCodeAt(index) looks at the string as a sequence of UTF-16 code units and returns the integer value of the unit at that position.

  • Indexes are zero-based — 0 is the first code unit.
  • Valid results are integers from 0 to 65535 (0xFFFF).
  • Missing position — returns NaN.
  • May return a lone surrogate for characters above U+FFFF.

📝 Syntax

General form of String.prototype.charCodeAt:

JavaScript
str.charCodeAt(index)

Parameters

  • index — zero-based position of the code unit. Converted to an integer (undefined becomes 0).

Return value

A number for the UTF-16 code unit at that index. Special cases:

SituationReturns
Valid index (0length - 1)Integer between 0 and 65535 (e.g. "A".charCodeAt(0)65)
No argument / undefinedSame as charCodeAt(0)
Index out of range (including negatives)NaN
Empty string at any indexNaN
High/low surrogate (emoji half)Lone surrogate unit (still 065535) — prefer codePointAt() for the full character

Common patterns

JavaScript
"ABC".charCodeAt(0);              // 65
"Hello".charCodeAt(4);            // 111  ("o")
"Hello".charCodeAt(10);           // NaN

// Round-trip with fromCharCode:
String.fromCharCode(65);          // "A"
String.fromCharCode("q".charCodeAt(0)); // "q"

// Full Unicode for emoji / rare chars:
"𠮷".codePointAt(0);               // 134071

⚡ Quick Reference

GoalCode
Code unit at indexstr.charCodeAt(i)
First code unitstr.charCodeAt(0)
Last code unitstr.charCodeAt(str.length - 1)
Out of rangeNaN
Number → characterString.fromCharCode(n)
Full Unicode valuestr.codePointAt(i)

🔍 At a Glance

Four facts to remember about String.charCodeAt().

Returns
number

0–65535 or NaN

Out of range
NaN

Not 0, not ""

Emoji risk
lone surrogate

Use codePointAt

Mutates
no

Strings stay immutable

📋 charCodeAt() vs codePointAt() vs charAt()

charCodeAt(i)codePointAt(i)charAt(i)
Result typeNumber (0–65535)Number (full code point)String (1 unit)
Out of rangeNaNundefined""
Emoji / U+10000+Lone surrogate possibleFull code pointLone surrogate possible
Best forUTF-16 unit mathTrue Unicode valueReading the character text

Examples Gallery

Examples follow MDN String.charCodeAt() patterns. Use View Output or Try It Yourself for each case.

📚 Getting Started

Read UTF-16 code units as numbers.

Example 1 — Basic charCodeAt()

MDN demo: print the code and the matching character.

JavaScript
const sentence = "The quick brown fox jumps over the lazy dog.";
const index = 4;

`Character code ${sentence.charCodeAt(index)} is equal to ${sentence.charAt(index)}`;
// "Character code 113 is equal to q"
Try It Yourself

How It Works

Index 4 is the letter "q". charCodeAt(4) returns 113; charAt(4) returns the same position as text.

Example 2 — Classic Letter Codes

MDN-style call: "A" has Unicode value 65.

JavaScript
"ABC".charCodeAt(0);  // 65
"ABC".charCodeAt(1);  // 66
"ABC".charCodeAt(2);  // 67

"a".charCodeAt(0);    // 97
"0".charCodeAt(0);    // 48
" ".charCodeAt(0);    // 32
Try It Yourself

How It Works

For basic Latin letters and digits, the UTF-16 code unit matches the familiar Unicode / ASCII value. Uppercase and lowercase differ by 32 ("A" = 65, "a" = 97).

📈 Practical Patterns

Bounds checks, round-trips, and Unicode caution.

Example 3 — Default Index & Out of Range

Missing index becomes 0; bad positions return NaN.

JavaScript
const s = "Hi";

s.charCodeAt();     // 72  (no index → 0 → "H")
s.charCodeAt(0);    // 72
s.charCodeAt(1);    // 105
s.charCodeAt(2);    // NaN
s.charCodeAt(-1);   // NaN
s.charCodeAt(999);  // NaN

Number.isNaN(s.charCodeAt(2));  // true
Try It Yourself

How It Works

Unlike charAt() (which returns ""), a missing index here is NaN. Negatives are not supported — use charCodeAt(str.length - 1) for the last unit.

Example 4 — Round-Trip with fromCharCode()

Turn a code unit back into a character (and the other way around).

JavaScript
const code = "Z".charCodeAt(0);           // 90
String.fromCharCode(code);                // "Z"

String.fromCharCode(72, 105);             // "Hi"

// Caesar-style shift by 1 (ASCII letters only):
function nextLetter(ch) {
  return String.fromCharCode(ch.charCodeAt(0) + 1);
}
nextLetter("A");  // "B"
nextLetter("y");  // "z"
Try It Yourself

How It Works

charCodeAt and fromCharCode are a natural pair for UTF-16 units. For full Unicode code points (emoji), use codePointAt / fromCodePoint instead.

Example 5 — Surrogate Pairs (Prefer codePointAt)

MDN note: charCodeAt may return a lone surrogate, not a full character.

JavaScript
const str = "𠮷𠮾";

str.charCodeAt(0);   // 55362  (0xD842 — high surrogate)
str.charCodeAt(1);   // 57271  (0xDFB7 — low surrogate)
str.length;          // 4      (two characters, four code units)

// Prefer code-point APIs for the full character:
str.codePointAt(0);  // 134071
String.fromCodePoint(str.codePointAt(0));  // "𠮷"
Try It Yourself

How It Works

Characters above U+FFFF need two UTF-16 units. Avoid rebuilding codePointAt by hand from surrogate pairs — use the built-in method.

🚀 Common Use Cases

  • Letter math — shift ASCII letters with fromCharCode(code ± n).
  • Digit / case checks — compare numeric ranges (48–57 digits, 65–90 A–Z).
  • Checksums & hashes — fold code units into a simple number.
  • Debugging encodings — inspect exact UTF-16 units in a string.
  • Pair with charAt — show both the glyph and its code in tutorials.
  • Not for full emoji — use codePointAt() / fromCodePoint().

🧠 How charCodeAt() Resolves an Index

1

Receive an index

Convert to an integer (undefined becomes 0).

Input
2

Check the range

Valid positions are 0 through length - 1.

Bounds
3

Read one UTF-16 unit

Return its integer value (065535).

Read
4

Or return NaN

If the index is outside the string (including negatives).

📝 Notes

  • charCodeAt() always indexes UTF-16 code units, not grapheme clusters.
  • Out-of-range indexes return NaN, not undefined or "".
  • charCodeAt(-1) is not the last unit — use charCodeAt(length - 1).
  • Calling charCodeAt() with no argument is the same as charCodeAt(0).
  • Values are always < 65536; larger Unicode needs codePointAt().
  • Do not re-implement codePointAt() by combining surrogate pairs yourself.

Browser & Runtime Support

String.prototype.charCodeAt() is Baseline Widely available — supported across browsers for many years.

Baseline · Widely available

String.charCodeAt()

Safe everywhere. Prefer codePointAt() when you need the full Unicode code point for emoji.

Universal Widely available
Google Chrome Supported · Desktop & Mobile
Full support
Mozilla Firefox Supported · Desktop & Mobile
Full support
Apple Safari Supported · macOS & iOS
Full support
Microsoft Edge Supported · Chromium
Full support
Internet Explorer No native support · Use a polyfill
Polyfill
Opera Supported · Modern versions
Full support
Samsung Internet Supported · Android
Full support
Bun Supported · JavaScript runtime
Supported
Deno Supported · JavaScript runtime
Supported
Node.js Supported · Server runtime
Supported
Android WebView Supported · Modern WebView
Full support
charCodeAt() Excellent

Bottom line: Use String.charCodeAt() for UTF-16 code unit numbers. Remember out-of-range returns NaN, and for characters above U+FFFF prefer codePointAt().

Conclusion

String.prototype.charCodeAt() turns a string index into a UTF-16 code unit number (065535), or NaN when the position is missing. Pair it with fromCharCode() for simple letter math, and reach for codePointAt() when full Unicode matters.

Continue with codePointAt(), charAt(), or the String methods hub.

💡 Best Practices

✅ Do

  • Use charCodeAt(i) for UTF-16 unit numbers
  • Check misses with Number.isNaN(...)
  • Pair with String.fromCharCode() for ASCII round-trips
  • Prefer codePointAt() for emoji / rare characters
  • Use charCodeAt(str.length - 1) for the last unit

❌ Don’t

  • Expect charCodeAt(-1) to return the last unit
  • Assume the number always equals a full Unicode character
  • Treat out-of-range results like 0 or ""
  • Hand-pair surrogates instead of using codePointAt()
  • Forget strings are immutable — this method only reads

Key Takeaways

Knowledge Unlocked

Five things to remember about String.charCodeAt()

UTF-16 code unit numbers with NaN for missing indexes.

5
Core concepts
🔢 02

Pair

fromCharCode

Pattern
03

Miss

NaN

Bounds
04

Emoji

codePointAt

Unicode
📄 05

Mutates

no

Immutable

❓ Frequently Asked Questions

String.prototype.charCodeAt(index) returns an integer between 0 and 65535 for the UTF-16 code unit at that zero-based index. If the index is out of range, it returns NaN.
charCodeAt() always returns one UTF-16 code unit (0–65535) and may return a lone surrogate for emoji. codePointAt() returns the full Unicode code point, which can be larger than 65535 for characters that use surrogate pairs.
NaN. That is different from charAt(), which returns an empty string "" for a missing index.
No. A negative index is out of range, so charCodeAt(-1) returns NaN. Use charCodeAt(str.length - 1) for the last code unit.
Use String.fromCharCode(code) for a UTF-16 code unit, or String.fromCodePoint(codePoint) when you have a full Unicode code point.
No. Strings are immutable. charCodeAt() only reads a number from the string.
Did you know?

Unicode code points go up to 0x10FFFF (over one million). charCodeAt() can never return a value that large — anything above 65535 is stored as two UTF-16 code units, which is why codePointAt() exists.

More String Methods

Return to the hub for slice, trim, replace, and more.

String methods hub →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

8 people found this page helpful