Lodash _.range() Method

Beginner
⏱️ 7 min read
📚 Updated: Jul 2026
🎯 6 Examples + 3 Try It
Util utilities

What You’ll Learn

By the end of this tutorial, you’ll use Lodash’s _.range() to build number arrays for loops, indexes, and pagination—without writing manual increment logic.

01

Core Syntax

_.range(start, end, step)

02

One arg

_.range(5) → 0..4

03

Exclusive end

End not included.

04

Custom step

Skip by 2, 5, etc.

05

Count down

Negative step.

06

vs rangeRight

Reverse order.

What Is _.range()?

_.range() creates an array of numbers in order—like Python’s range. You control where the sequence starts, where it stops (exclusive), and how much it steps each time. It is one of the most practical Lodash helpers for replacing for (let i = 0; i < n; i++) when you need the index array itself.

💡
Beginner tip — one argument means “0 up to n”

_.range(5) is [0, 1, 2, 3, 4]. The lone number is the end, not the start. Start defaults to 0.

Use range for iteration helpers, zero-based indexes, page-number lists, chart tick marks, and any time you need a predictable numeric sequence in one expression.

📝 Syntax

All arguments are optional except that you need at least one value for a non-empty result:

javascript
_.range([start = 0], end, [step = 1 or -1])

Syntax Rules

  • One argument — treated as end; start is 0. _.range(4)[0, 1, 2, 3].
  • Two argumentsstart and end (exclusive). Step defaults to 1 if start < end, else -1.
  • Three arguments — explicit step (can be negative for countdowns).
  • End is exclusive — the stop value never appears in the output array.
  • Empty result_.range(0) returns []; invalid step/end combos may also yield [].
javascript
import range from "lodash/range";



range(1, 6, 2);

// [1, 3, 5]

⚡ Quick Reference

TaskCode patternResult
Zero to n − 1_.range(n)[0..n−1]
Start to end_.range(1, 5)[1, 2, 3, 4]
Step by 2_.range(0, 10, 2)[0, 2, 4, 6, 8]
Countdown_.range(5, 0, -1)[5, 4, 3, 2, 1]
Loop indexes_.range(items.length)0..len−1
Descending order_.rangeRight(...)Reversed
Returns
Array

Numbers

End
Exclusive

Not included

Default step
±1

By direction

Category
Util

Sequence

🧰 Parameters

Arguments to _.range() and how they shape the output:

start Optional

First value in the sequence. Defaults to 0 when only one argument is passed (that arg becomes end).

_.range(2, 5) // start 2
end Required*

Stop boundary—exclusive. With one arg, it is the only number you pass: _.range(end).

_.range(1, 5) // stops before 5
step Optional

Increment (or decrement when negative). Defaults to 1 or -1 based on start vs end.

_.range(0, 20, 5)
return Array

Dense array of numbers following the progression until the next step would reach or pass end.

[0, 1, 2, 3, 4]

Official edge case: _.range(1, 4, 0) repeats 1 (step zero)—rare in practice; prefer positive or negative steps.

Examples Gallery

Practical _.range() patterns with copy-ready code, sample output, and interactive Try It Yourself labs.

📚 Getting Started

Start, end, and step—the core progression pattern.

Example 1 — Custom start, end, and step

From 1 up to (but not including) 6, stepping by 2.

javascript
console.log(_.range(1, 6, 2));

// [1, 3, 5]
Try It Yourself

How It Works

Values are 1, then +2 → 3, then +2 → 5. Next would be 7, which reaches past end 6, so the array stops.

Example 2 — One-argument and two-argument forms

Common shorthands from the Lodash docs.

javascript
console.log(_.range(5));

console.log(_.range(1, 10, 2));

console.log(_.range(0));

// [0, 1, 2, 3, 4]

// [1, 3, 5, 7, 9]

// []

How It Works

_.range(5) means “zero up to five (exclusive).” _.range(0) has nowhere to go, so you get an empty array.

Example 3 — Official Lodash demos

Includes negative direction when start and end flip.

javascript
console.log(_.range(4));

console.log(_.range(-4));

console.log(_.range(1, 5));

console.log(_.range(0, 20, 5));

console.log(_.range(0, -4, -1));

// [0, 1, 2, 3]

// [0, -1, -2, -3]

// [1, 2, 3, 4]

// [0, 5, 10, 15]

// [0, -1, -2, -3]

How It Works

_.range(-4) is shorthand for start 0, end -4, default step -1—handy to remember when the lone argument is negative.

📈 Practical Patterns

Loops, pagination, and countdown sequences.

Example 4 — Countdown with negative step

When start is greater than end, pass a negative step (or rely on the default -1 with two args).

javascript
console.log(_.range(5, 1, -1));

console.log(_.range(5, 0, -1));

// [5, 4, 3, 2]

// [5, 4, 3, 2, 1]
Try It Yourself

How It Works

End is still exclusive: _.range(5, 1, -1) stops before 1, so 1 is omitted. Include zero by using end 0 with step -1 carefully, or use _.range(5, 0, -1).

Example 5 — Pagination page numbers

Build [1, 2, …, totalPages] for a pager UI.

javascript
const itemsPerPage = 10;

const totalItems = 87;

const totalPages = Math.ceil(totalItems / itemsPerPage);



const pageNumbers = _.range(1, totalPages + 1);



console.log(pageNumbers);

// [1, 2, 3, 4, 5, 6, 7, 8, 9]
Try It Yourself

How It Works

Pages are 1-based, so start at 1 and use end totalPages + 1 because end is exclusive.

🚀 Beyond the Basics

range vs native alternatives and rangeRight.

Example 6 — range vs Array.from vs rangeRight

Same length indexes—different APIs. Descending values vs descending array order.

javascript
// Lodash range — explicit start/end/step

console.log(_.range(2, 5));

// [2, 3, 4]



// Native — length-based indexes

console.log(Array.from({ length: 3 }, (_, i) => i + 2));

// [2, 3, 4]



// Same numbers, reversed array order (see rangeRight tutorial)

console.log(_.rangeRight(2, 5));

// [4, 3, 2]

When to use which

Need countdown values? Use negative step with range. Need the array stored high-to-low? Use rangeRight.

🧠 How _.range() Works

1

Normalize args

One arg → start 0, that arg is end. Infer step sign from start vs end if omitted.

Setup
2

Walk the progression

Push current value, add step, repeat until the next value would cross end.

Build
3

Respect exclusive end

The end boundary itself is never pushed—same rule as Python range.

Stop rule
=

Number array

A dense list ready for map, for…of, pagination UI, or index lookups.

📝 Notes

  • _.range(n) is 0 through n - 1, not 1 through n.
  • End is always exclusive—add 1 when you need an inclusive upper bound (e.g. pagination).
  • Count down with a negative step; do not assume two-arg reverse works without checking default step rules.
  • Very large ranges allocate a full array—avoid _.range(1_000_000) unless you truly need every index in memory.
  • For reversed output order with the same numeric progression, see _.rangeRight().
  • Next in the series: _.rangeRight()—same numbers, opposite array order.

Conclusion

_.range() is the quick way to materialize numeric sequences in JavaScript. Once you internalize “one arg = end, exclusive stop,” it becomes a go-to for indexes, pagers, and loop helpers.

Pair it with collection methods (_.map(_.range(n), …)) or use native for…of—choose the style that reads best in your project.

💡 Best Practices

✅ Do

  • Use _.range(n) for 0-based indexes of length n
  • Add 1 to end for inclusive upper bounds (page numbers starting at 1)
  • Pass explicit negative step for countdown sequences
  • Combine with _.map to build derived arrays from indexes
  • Prefer small, readable ranges over million-element allocations

❌ Don’t

  • Assume _.range(5) includes 5—it stops at 4
  • Use broken self-referential spreads (e.g. fibonacci via range map on itself)
  • Confuse range with rangeRight when you only need descending values—negative step may suffice
  • Build huge ranges when you only need lazy iteration
  • Pass step 0 unless you intentionally want repeated values

Key Takeaways

Knowledge Unlocked

Five things to remember about _.range()

Use these points whenever you need a numeric sequence array.

5
Core concepts
🔄 02

_.range(n)

0 .. n−1.

Shorthand
03

Step

Custom stride.

Control
📝 04

Negative step

Count down.

Pattern
🛠 05

rangeRight

Reverse order.

Compare

❓ Frequently Asked Questions

_.range(start, end, step) returns an array of numbers forming an arithmetic progression. It is like Python's range—handy for loops, indexes, and pagination without manual for loops.
The single value is the end (exclusive) and start defaults to 0. _.range(5) yields [0, 1, 2, 3, 4]. _.range(0) yields an empty array.
Exclusive—the end number is never included. _.range(1, 5) is [1, 2, 3, 4], not including 5.
Use a negative step when start is greater than end: _.range(5, 0, -1) gives [5, 4, 3, 2, 1]. With two args where start > end, step defaults to -1.
Both build the same numbers; rangeRight returns them in reverse order (end toward start). Use range for ascending sequences; rangeRight when you need descending array order.
Use _.range when you want explicit start/end/step math. Array.from({ length: n }, (_, i) => i) is fine for simple 0..n-1 indexes. Pick whichever reads clearer in your codebase.
Did you know?

Lodash’s _.range(-4) yields [0, -1, -2, -3] because the single argument becomes an exclusive end below zero with default step -1—not a length of four positive numbers.

Practice _.range() in the Live Editor

Try step-by-two sequences, countdown ranges, and pagination page numbers.

Open Try It editor →

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.

6 people found this page helpful