Array.prototype.flat()

The default depth is 1, not infinite — the mistake almost everyone makes on first use. Pass Infinity when you genuinely want it flat all the way down.

Array methodES2019Live demo
Common call
nested.flat()
Returns
a new array, one level flatter
Replaces
the old [].concat(...arrays) trick
Watch out
the default depth is 1; use flat(Infinity) for fully flat
array.flat([depth])
→ Array

Demo

Live evaluation
Try:
Inputs
depthnumberlevels to flatten (try 1, 2, 3)
Output
[1, [2, [3, [4]]]].flat(1)
[1, 2, [3, [4]]]

The input is nested three levels deep. Each increment of depth peels off exactly one layer, so depth 1 — the DEFAULT — leaves [3, [4]] still nested inside. That is the surprise: calling flat() with no argument on deeply nested data looks like it did almost nothing. Depth 0 returns the array unchanged, and only depth 3 (or Infinity) flattens this particular input completely.

Parameters

NameTypeRequiredDescription
depthnumberno (1)How many levels to flatten. 0 returns a shallow copy unchanged. Infinity flattens completely however deep the nesting goes.

Return value

Array — A NEW array with nested arrays spliced in up to the given depth. Empty slots (holes) are removed along the way.

Common patterns

Flatten completely
Infinity when the nesting depth is unknown.
const allValues = nested.flat(Infinity);
Map then flatten
flatMap does both in one pass and is the usual intent.
const words = lines.flatMap(l => l.split(" "));
Remove holes from a sparse array
A side effect of flat that is occasionally exactly what you want.
const dense = sparse.flat();

Examples

1. Default depth is 1
[1, [2, [3, [4]]]].flat()
Returns
[1, 2, [3, [4]]]
2. Depth 2
[1, [2, [3, [4]]]].flat(2)
Returns
[1, 2, 3, [4]]
3. Fully flat
[1, [2, [3, [4]]]].flat(Infinity)
Returns
[1, 2, 3, 4]
4. Depth 0 is a copy
[1, [2]].flat(0)
Returns
[1, [2]]
5. Simple case
[[1], [2]].flat()
Returns
[1, 2]
6. Holes are removed
[1, , 3].flat()
Returns
[1, 3]

Pitfalls

1. The default depth is 1, not Infinity
Calling flat() on data nested more than one level deep leaves the inner arrays intact. Because the outer layer DID flatten, it looks like the method half-worked rather than like a missing argument.
Still nested
[1, [2, [3]]].flat()
[1, 2, [3]]
Say how deep
[1, [2, [3]]].flat(Infinity)
[1, 2, 3]
2. It silently removes holes
Empty slots in a sparse array disappear, so the length can shrink even with depth 0 on a sparse input. Handy when you want it, surprising when the length matters.
Length changed
[1, , 3].flat().length
2 // was 3
Keep the slots
[1, , 3].map(x => x)
holes preserved
3. map().flat() when flatMap() was meant
Chaining builds an intermediate array that is immediately thrown away. flatMap does it in one pass, and states the intent — though note flatMap only ever flattens ONE level.
Two passes
lines.map(l => l.split(" ")).flat()
works, allocates twice
One pass
lines.flatMap(l => l.split(" "))
same result
4. ES2019 and newer only
Not available in older runtimes or Internet Explorer. The pre-2019 idiom was concat with a spread, which flattens exactly one level.
Missing method
nested.flat()
TypeError: nested.flat is not a function
Old idiom
[].concat(...nested)
one level flatter

When to use

Use it
  • Flattening arrays of arrays into a single list
  • Normalising deeply nested data with Infinity
  • Removing holes from a sparse array
Reach for something else
  • You are mapping then flattening → flatMap
  • The nesting is deeper than one level and you called flat() → pass a depth
  • Runtimes older than ES2019 → [].concat(...arrays)

Notes

Complexity
O(n) in the total number of elements across all flattened levels
Return
A new array; the original is never modified
CPython impl
V8: Builtins-array-flat.tq
Memory
Allocates a new array; deep nesting recurses per level
Thread-safe
Single-threaded; the source is only read

FAQ

Because the default depth is 1 — it removes exactly one level of nesting. Anything deeper stays as it is. Pass Infinity to flatten completely regardless of how deep the structure goes.

[1, [2, [3]]].flat()          // [1, 2, [3]]
[1, [2, [3]]].flat(Infinity)  // [1, 2, 3]

History

ES2019
flat and flatMap added. The proposal was briefly named flatten, renamed after it broke MooTools on the live web.