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
Fundamentals
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(...).
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.
Foundation
📝 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:
Situation
Returns
Valid index (0 … length - 1)
Integer between 0 and 65535 (e.g. "A".charCodeAt(0) → 65)
No argument / undefined
Same as charCodeAt(0)
Index out of range (including negatives)
NaN
Empty string at any index
NaN
High/low surrogate (emoji half)
Lone surrogate unit (still 0–65535) — 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
Cheat Sheet
⚡ Quick Reference
Goal
Code
Code unit at index
str.charCodeAt(i)
First code unit
str.charCodeAt(0)
Last code unit
str.charCodeAt(str.length - 1)
Out of range
NaN
Number → character
String.fromCharCode(n)
Full Unicode value
str.codePointAt(i)
Snapshot
🔍 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
Compare
📋 charCodeAt() vs codePointAt() vs charAt()
charCodeAt(i)
codePointAt(i)
charAt(i)
Result type
Number (0–65535)
Number (full code point)
String (1 unit)
Out of range
NaN
undefined
""
Emoji / U+10000+
Lone surrogate possible
Full code point
Lone surrogate possible
Best for
UTF-16 unit math
True Unicode value
Reading the character text
Hands-On
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"
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
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 (0–65535).
Read
4
✅
Or return NaN
If the index is outside the string (including negatives).
Important
📝 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.
Compatibility
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.
UniversalWidely available
Google ChromeSupported · Desktop & Mobile
Full support
Mozilla FirefoxSupported · Desktop & Mobile
Full support
Apple SafariSupported · macOS & iOS
Full support
Microsoft EdgeSupported · Chromium
Full support
Internet ExplorerNo native support · Use a polyfill
Polyfill
OperaSupported · Modern versions
Full support
Samsung InternetSupported · Android
Full support
BunSupported · JavaScript runtime
Supported
DenoSupported · JavaScript runtime
Supported
Node.jsSupported · Server runtime
Supported
Android WebViewSupported · 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().
Wrap Up
Conclusion
String.prototype.charCodeAt() turns a string index into a UTF-16 code unit number (0–65535), or NaN when the position is missing. Pair it with fromCharCode() for simple letter math, and reach for codePointAt() when full Unicode matters.
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
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about String.charCodeAt()
UTF-16 code unit numbers with NaN for missing indexes.
5
Core concepts
📝01
Returns
0–65535 / NaN
API
🔢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.