String.prototype.substr() extracts characters by start index + length (same API as MDN String.prototype.substr()). Learn why it is deprecated, how negatives work, how it differs from slice() / substring(), five examples, and try-it labs.
01
Kind
Instance method
02
Returns
New string
03
2nd arg
Length
04
Status
Deprecated
05
Mutates?
No
06
Prefer
slice()
Fundamentals
Introduction
Need “start here, take this many characters”? That is what substr(start, length) does. It returns a new string and never changes the original.
Today you should reach for slice() instead. substr() is deprecated and optional outside browsers. Still, you will see it in older tutorials and codebases — so it helps to recognize the length-based API.
💡
Beginner tip
substr ≠ sub ≠ substring. sub() builds <sub> HTML. substring() uses two indexes. substr() uses start + length (legacy).
Migrating old scripts — rewrite to slice() carefully.
Teaching differences — show length vs end-index APIs.
Not for new apps — do not introduce substr() in fresh projects.
Not HTML subscript — that is the deprecated sub() wrapper.
Not delimiter splits — use split() for CSV / words.
🧠 How substr() Builds the Result
1
Read start / length
Default start to 0; default length to “rest of string.”
Input
2
Normalize negatives
Negative start → from end; negative length → empty result.
Adjust
3
Copy characters
Take up to length characters from the normalized start.
Extract
4
⚠️
Prefer slice() instead
Use the standard end-index API in new code.
Important
📝 Notes
substr() is deprecated (Annex B / web compatibility).
The second argument is a length, not an end index.
Negative length returns "" — unlike slice.
Do not confuse with sub() (HTML) or substring() (two indexes).
Blindly replacing with slice(a, a + l) can change behavior.
Always capture the return value — the original string is unchanged.
Compatibility
Browser & Runtime Support
String.prototype.substr() is still widely implemented for compatibility, but it is deprecated. Prefer slice() for portable new code.
✓ Deprecated · Annex B
String.substr()
Available in browsers for legacy code. Not part of the main ECMAScript path — use slice() or substring() instead.
LegacyCompatibility only
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
substr()Avoid in new code
Bottom line: Recognize substr() in legacy samples. For new extraction, use String.slice() with start/end indexes.
Wrap Up
Conclusion
String.prototype.substr() extracts by start and length — a legacy shape that still appears in older code. Learn it to migrate safely, then write new features with slice().
Assume slice(a, a + l) always matches substr(a, l)
Pass negative lengths expecting characters
Forget strings are immutable — use the return value
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about String.substr()
Legacy start + length extractor — prefer slice().
5
Core concepts
📝01
Returns
new string
API
🔢02
2nd arg
length
Rule
⚠️03
Status
deprecated
Legacy
✓04
Prefer
slice()
Modern
⚡05
Mutates
no
Immutable
❓ Frequently Asked Questions
String.prototype.substr(start, length?) returns a new string with length characters beginning at start. The original string is unchanged.
Yes. MDN marks it as deprecated. It lives in ECMAScript Annex B (web compatibility). Prefer String.prototype.slice() or substring() in new code.
In substr(), the second argument is a length (how many characters). In slice() and substring(), the second argument is an end index (exclusive).
A negative start counts from the end of the string — for example "Mozilla".substr(-3) returns "lla". Negative length returns an empty string "".
No. sub() is a deprecated HTML wrapper that builds <sub> markup. substr() extracts characters by start and length.
Not always. When length is negative they differ — substr returns "", while slice(a, a + l) may still return characters. Prefer slice with known non-negative lengths, or rewrite carefully.
Did you know?
substr() is defined in ECMAScript Annex B — features kept mainly for web-browser compatibility. Non-browser runtimes are not required to implement it, which is another reason to prefer slice() for portable code.