JavaScript String substring() Method

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

What You’ll Learn

String.prototype.substring() extracts characters from a start index up to (but not including) an end index (same API as MDN String.prototype.substring()). Learn argument swapping, how negatives become 0, how it compares to slice() and substr(), five examples, and try-it labs.

01

Kind

Instance method

02

Returns

New string

03

End index

Exclusive

04

If start > end

Args swap

05

Negatives

Treated as 0

06

Baseline

Widely available

Introduction

Need characters between two indexes? substring(start, end) copies that window into a new string. The end index is exclusive — just like slice().

Two quirks to remember: if start is greater than end, the arguments are swapped; and negative numbers are treated as 0 (they do not count from the end). For end-relative indexes, prefer slice().

💡
Beginner tip

substringsubstrsub. substring uses two indexes. substr uses length (legacy). sub builds HTML <sub> tags.

This page is part of JavaScript String Methods. Related topics include slice() and substr().

Understanding the substring() Method

str.substring(indexStart, indexEnd) returns characters from indexStart until indexEnd (exclusive).

  • Creates a new string; the original is unchanged.
  • indexEnd is optional — omit it to extract to the end.
  • If start > end, the two arguments are swapped.
  • Values below 0 or NaN are treated as 0.

📝 Syntax

General form of String.prototype.substring:

JavaScript
str.substring(indexStart)
str.substring(indexStart, indexEnd)

Parameters

  • indexStart — index of the first character to include. Values < 0 or NaN become 0. Values > str.length become str.length.
  • indexEnd (optional) — index of the first character to exclude. Same clamping rules. Omit to go to the end.

Return value

A string with the extracted section:

SituationResult
Normal rangeCharacters from start up to (not including) end
End omittedFrom start to the end of the string
Start === endEmpty string ""
Start > endArguments are swapped, then extracted
Negative / NaN argsTreated as 0

Common patterns

JavaScript
"Mozilla".substring(1, 3);  // "oz"
"Mozilla".substring(2);     // "zilla"
"Mozilla".substring(5, 2);  // "zil" (swapped)
"Mozilla".substring(-5, 2); // "Mo"  (negatives → 0)

⚡ Quick Reference

GoalCode
Between two indexesstr.substring(start, end)
From index to endstr.substring(i)
Last n charactersstr.substring(str.length - n)
Last n (prefer)str.slice(-n)
First n charactersstr.substring(0, n)

🔍 At a Glance

Four facts to remember about String.substring().

Returns
string

Extracted section

End
exclusive

Not included

Start > end
swap

Still returns text

Negatives
→ 0

Not from the end

📋 substring() vs slice() vs substr()

substring()slice()substr()
Second argumentEnd index (exclusive)End index (exclusive)Length (legacy)
If start > endArguments swappedEmpty string ""Uses length
Negative indexesTreated as 0Count from endStart from end (legacy)
RecommendationOK for non-negativesPrefer (esp. negatives)Avoid (deprecated)

Examples Gallery

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

📚 Getting Started

Basic ranges and omitting the end index.

Example 1 — Basic substring()

MDN demo: extract from "Mozilla".

JavaScript
const str = "Mozilla";

str.substring(1, 3);
// "oz"

str.substring(2);
// "zilla"
Try It Yourself

How It Works

substring(1, 3) keeps indexes 1 and 2. Omitting the end takes everything from index 2 onward.

Example 2 — Swapped Arguments and Bounds

MDN demo: start > end still returns text; oversized ends clamp.

JavaScript
const anyString = "Mozilla";

anyString.substring(0, 1);  // "M"
anyString.substring(1, 0);  // "M"  (swapped)
anyString.substring(4, 7);  // "lla"
anyString.substring(7, 4);  // "lla" (swapped)
anyString.substring(0, 10); // "Mozilla"
Try It Yourself

How It Works

Order of the two indexes does not matter for the window — substring sorts them. Ends past length stop at the string’s end.

📈 Practical Patterns

Length math, slice differences, and everyday helpers.

Example 3 — Last Characters with length

MDN demo: take a suffix without negative indexes.

JavaScript
const text = "Mozilla";

text.substring(text.length - 4); // "illa"
text.substring(text.length - 5); // "zilla"

// Cleaner with slice:
text.slice(-4); // "illa"
text.slice(-5); // "zilla"
Try It Yourself

How It Works

Because negatives are not “from the end” in substring, you compute length - n yourself — or switch to slice(-n).

Example 4 — substring() vs slice()

MDN demos: swap behavior and negative arguments.

JavaScript
const text = "Mozilla";

text.substring(5, 2); // "zil"
text.slice(5, 2);     // ""

text.substring(-5, 2); // "Mo"
text.substring(-5, -2); // ""

text.slice(-5, -2); // "zil"
Try It Yourself

How It Works

substring is forgiving about argument order and strict about negatives (clamp to 0). slice keeps order and supports end-relative indexes.

Example 5 — Replace Text with Split / Join

MDN note: prefer replace or split+join over manual substring loops.

JavaScript
function replaceString(oldS, newS, fullS) {
  return fullS.split(oldS).join(newS);
}

replaceString("World", "Web", "Brave New World");
// "Brave New Web"

"Mozilla".substring(0, 3);
// "Moz"
Try It Yourself

How It Works

Use substring for index windows. For search-and-replace, reach for replace() or split/join instead of hand-rolled loops.

🚀 Common Use Cases

  • Take a prefix / mid-sectionsubstring(0, n) or substring(a, b).
  • Drop a known prefix lengthsubstring(prefix.length).
  • Last n chars without negativessubstring(str.length - n).
  • Order-independent windows — when you want swap behavior if start > end.
  • Prefer slice for suffixesslice(-n) is clearer than length math.
  • Not for delimiter cuts — use split() for CSV / words.

🧠 How substring() Builds the Result

1

Read start / end

Default end to the string length when omitted.

Input
2

Clamp and swap

Negatives / NaN → 0; if start > end, swap them.

Normalize
3

Copy the window

Copy from start up to (not including) end.

Extract
4

Return a new string

Original str never changes.

📝 Notes

  • The end index is exclusive.
  • If start > end, the arguments are swapped (unlike slice).
  • Negative values and NaN are treated as 0.
  • Do not confuse with deprecated substr() (length-based).
  • Prefer slice(-n) for suffixes instead of length - n math.
  • Always capture the return value — the original string is unchanged.

Browser & Runtime Support

String.prototype.substring() is Baseline Widely available — supported across modern browsers since July 2015 (and far earlier as a core language feature).

Baseline · Widely available

String.substring()

Safe for production in browsers and runtimes (Node.js, Deno, Bun). Prefer slice() when you need negative indexes.

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
substring() Excellent

Bottom line: Use String.substring() to copy between two indexes. Remember it swaps if start > end, and negatives become 0 — use slice() for end-relative cuts.

Conclusion

String.prototype.substring() extracts between two indexes with an exclusive end. It is a solid, standard tool — just remember the swap rule and that negatives are not “from the end.” For end-relative work, prefer slice(); avoid legacy substr().

Continue with slice(), substr(), or the String methods hub.

💡 Best Practices

✅ Do

  • Use substring for clear start/end index windows
  • Prefer slice(-n) for last-n characters
  • Remember the end index is exclusive
  • Use replace / split+join for text replacement
  • Assign the returned string to a variable

❌ Don’t

  • Expect negatives to count from the end
  • Confuse substring with deprecated substr
  • Assume start > end returns "" (it swaps)
  • Hand-roll replace loops with substring when replace exists
  • Mutate strings — always use the return value

Key Takeaways

Knowledge Unlocked

Five things to remember about String.substring()

Extract between indexes — exclusive end, swap if reversed.

5
Core concepts
✂️ 02

End

exclusive

Rule
🔁 03

Start > end

swaps

Quirk
🔙 04

Negatives

become 0

Index
05

Mutates

no

Immutable

❓ Frequently Asked Questions

String.prototype.substring(indexStart, indexEnd?) returns a new string from indexStart up to (but not including) indexEnd. Omit indexEnd to go to the end of the string.
No. indexEnd is exclusive — the character at indexEnd is not included. For example "Mozilla".substring(1, 3) returns "oz".
substring() swaps the two arguments. So "Mozilla".substring(5, 2) is the same as "Mozilla".substring(2, 5) and returns "zil". slice() would return "" instead.
Unlike slice(), substring() treats negative values (and NaN) as 0. It does not count from the end of the string.
substring(start, end) uses two indexes. substr(start, length) uses a length (and is deprecated). Prefer substring or slice over substr.
Both are fine for non-negative indexes. Prefer slice() when you need negative indexes from the end. Prefer substring() only if you rely on its swap-when-start-greater-than-end behavior.
Did you know?

"Mozilla".substring(1, 0) and "Mozilla".substring(0, 1) both return "M" because substring swaps when start > end. The same call with slice(1, 0) returns an empty string — a classic interview gotcha.

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