JavaScript String indexOf() Method

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

What You’ll Learn

String.prototype.indexOf() returns the first index of a substring, or -1 if it is missing (same API as MDN String.prototype.indexOf()). Learn the optional start position, case sensitivity, empty-string quirks, how to find the next match, how it compares to includes(), five examples, and try-it labs.

01

Kind

Instance method

02

Returns

index or -1

03

Case

Sensitive

04

vs includes

Needs the index

05

Mutates?

No

06

Baseline

Widely available

Introduction

When you need to know where a substring starts — not only whether it exists — use indexOf(). It returns a zero-based index, or -1 when nothing matches.

The search is case-sensitive. Pass a second argument to start searching later in the string (handy for finding the second occurrence). For a simple yes/no check, prefer includes().

💡
Beginner tip

Test for a miss with === -1 (or !== -1 for a hit). Do not treat 0 as “not found” — index 0 is a valid match at the start of the string.

This page is part of JavaScript String Methods. Related topics include includes() and length.

Understanding the indexOf() Method

indexOf(searchString, position) scans from position (default 0) and returns the first index where the substring begins.

  • Indexes are zero-based — the first character is at 0.
  • Missing substring — returns -1.
  • Matching is case-sensitive and exact.
  • Negative position is treated like 0.

📝 Syntax

General forms of String.prototype.indexOf:

JavaScript
str.indexOf(searchString)
str.indexOf(searchString, position)

Parameters

  • searchString — the substring to look for. Coerced to a string (undefined becomes "undefined").
  • position (optional) — start looking at this index (and after). Defaults to 0. Values < 0 behave like 0. Values ≥ str.length skip the search and return -1 (except for an empty needle — see below).

Return value

A number — the first matching index, or -1. Special cases:

SituationReturns
Substring foundFirst index ≥ position (e.g. "abc".indexOf("b")1)
Substring missing-1
Empty needle, position inside stringSame as position (default 0)
Empty needle, position ≥ lengthstr.length
Case differs-1 (e.g. "Hi".indexOf("hi"))
Negative positionTreated as 0

Common patterns

JavaScript
"Brave new world".indexOf("new");  // 6
"Brave new world".indexOf("w");    // 8
"Brave new world".indexOf("xyz");  // -1

// Next occurrence after the first:
const s = "dog and dog";
const first = s.indexOf("dog");           // 0
const second = s.indexOf("dog", first + 1); // 8

// Existence check (prefer includes for clarity):
s.indexOf("dog") !== -1;  // true
s.includes("dog");        // true

⚡ Quick Reference

GoalCode
First indexstr.indexOf(needle)
Search from an indexstr.indexOf(needle, start)
Not found?=== -1
Exists? (boolean)str.includes(needle) or indexOf !== -1
Case-insensitivestr.toLowerCase().indexOf(needle.toLowerCase())
Last occurrencestr.lastIndexOf(needle)

🔍 At a Glance

Four facts to remember about String.indexOf().

Returns
number

Index or -1

Case
sensitive

Normalize if needed

Miss
-1

Not 0, not false

Mutates
no

Strings stay immutable

📋 indexOf() vs includes() vs lastIndexOf()

indexOf()includes()lastIndexOf()
ResultFirst index or -1true / falseLast index or -1
Best forNeed the positionSimple contains checksSearch from the end
CaseSensitiveSensitiveSensitive
Start / fromIndexOptional positionOptional positionOptional from-index

Examples Gallery

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

📚 Getting Started

Find the first index of a substring.

Example 1 — Basic indexOf()

MDN-style lookups in "Brave new world".

JavaScript
const str = "Brave new world";

str.indexOf("w");    // 8
str.indexOf("new");  // 6
str.indexOf("xyz");  // -1
Try It Yourself

How It Works

"w" first appears in "world" at index 8. "new" starts at 6. A missing needle returns -1.

Example 2 — First and Second Occurrence

MDN demo: find "dog", then search again after that index.

JavaScript
const paragraph = "I think Ruth's dog is cuter than your dog!";
const searchTerm = "dog";
const indexOfFirst = paragraph.indexOf(searchTerm);

`The index of the first "${searchTerm}" is ${indexOfFirst}`;
// 'The index of the first "dog" is 15'

`The index of the second "${searchTerm}" is ${
  paragraph.indexOf(searchTerm, indexOfFirst + 1)
}`;
// 'The index of the second "dog" is 38'
Try It Yourself

How It Works

Pass indexOfFirst + 1 so the second search cannot re-match the first "dog". This pattern scales to a loop for every match.

📈 Practical Patterns

Case folding, counting matches, and empty-string quirks.

Example 3 — Case Sensitivity

MDN note: capitalization must match exactly.

JavaScript
const myString = "brie, pepper jack, cheddar";
const myCapString = "Brie, Pepper Jack, Cheddar";

myString.indexOf("cheddar");     // 19
myCapString.indexOf("cheddar");  // -1

myCapString.toLowerCase().indexOf("cheddar");  // 19
Try It Yourself

How It Works

Lower-casing the haystack (and needle when needed) makes the search ignore capital letters.

Example 4 — Count Occurrences

MDN pattern: walk the string with indexOf in a loop.

JavaScript
const str = "To be, or not to be, that is the question.";
let count = 0;
let position = str.indexOf("e");

while (position !== -1) {
  count++;
  position = str.indexOf("e", position + 1);
}

count;  // 4
Try It Yourself

How It Works

Each successful find advances position by one so the next search continues after the previous match. Stop when indexOf returns -1.

Example 5 — Empty String, Position Rules, Existence Check

MDN empty-needle quirks plus the classic !== -1 test.

JavaScript
"hello world".indexOf("");      // 0
"hello world".indexOf("", 3);   // 3
"hello world".indexOf("", 22);  // 11  (clamped to length)

"hello world hello".indexOf("o", -5);     // 4  (negative → 0)
"hello world hello".indexOf("world", 12); // -1

"Blue Whale".indexOf("Blue") !== -1;  // true
"Blue Whale".indexOf("Wale") !== -1;  // false
"Blue Whale".includes("Blue");        // true (clearer boolean)
Try It Yourself

How It Works

An empty needle “matches” at the start position (or at the end if you start past the string). Prefer includes() when you only need a boolean.

🚀 Common Use Cases

  • Locate a token — find where a keyword or delimiter starts.
  • Slice around a match — use the index with slice / substring.
  • Walk every match — loop with indexOf(needle, pos + 1).
  • Legacy existence checks!== -1 in older codebases.
  • Not for patterns — use regex when you need wildcards or flags.
  • Prefer includes for booleans — clearer intent for yes/no checks.

🧠 How indexOf() Finds an Index

1

Receive needle + start

Coerce searchString; clamp negative position to 0.

Input
2

Scan forward

Look for the first exact, case-sensitive match at/after position.

Search
3

Handle empty needle

Empty string matches at position (or at length if past the end).

Special
4

Return index or -1

Use the number for slicing, looping, or an existence check.

📝 Notes

  • indexOf() is case-sensitive.
  • A miss returns -1 — never confuse that with index 0.
  • Negative position is treated as 0.
  • Empty searchString has special return rules (see the table above).
  • Omitting the needle (or passing undefined) searches for "undefined".
  • Prefer includes() when you only need a boolean.

Browser & Runtime Support

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

Baseline · Widely available

String.indexOf()

Safe for production. Use indexOf() when you need the match index; prefer includes() for simple true/false checks.

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

Bottom line: Use String.indexOf() to locate the first substring index. Remember -1 means missing, searches are case-sensitive, and empty needles have special behavior.

Conclusion

String.prototype.indexOf() finds the first index of a substring (or -1 if missing), with an optional start position for finding the next match. Reach for includes() when you only need yes/no, and keep case rules and empty-needle quirks in mind.

Continue with lastIndexOf(), includes(), or the String methods hub.

💡 Best Practices

✅ Do

  • Use indexOf when you need the match position
  • Check misses with === -1
  • Advance with pos + 1 to find the next occurrence
  • Prefer includes() for simple contains checks
  • Normalize case when matches should ignore capitalization

❌ Don’t

  • Treat index 0 as “not found”
  • Forget that searches are case-sensitive
  • Ignore empty-needle special cases
  • Omit the needle and expect a useful default search
  • Use indexOf when a boolean is all you need

Key Takeaways

Knowledge Unlocked

Five things to remember about String.indexOf()

First match index, or -1 when missing.

5
Core concepts
🔎 02

Next match

pos + 1

Pattern
03

Miss

-1

Bounds
04

vs includes

index vs boolean

Compare
📄 05

Mutates

no

Immutable

❓ Frequently Asked Questions

String.prototype.indexOf(searchString, position?) returns the zero-based index of the first occurrence of searchString at or after position. If nothing is found, it returns -1.
Yes. "Blue Whale".indexOf("blue") returns -1. Normalize with toLowerCase() when you need a case-insensitive search.
Compare with -1: str.indexOf(needle) !== -1. For a clearer boolean, prefer str.includes(needle).
With no position (or a position inside the string), it returns that position (default 0). If position is past the end, it returns str.length.
indexOf() returns the first index or -1. includes() returns true or false. Use indexOf when you need the position; use includes for simple yes/no checks.
No. Strings are immutable. indexOf() only reads and returns a number.
Did you know?

indexOf existed long before includes. Older tutorials almost always taught str.indexOf(x) !== -1 for “contains” checks — today str.includes(x) is clearer, but indexOf remains essential whenever you need the actual index.

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