# oxc/no-accumulating-spread

> Disallow spreading the accumulator in `reduce()` and in loops

`[...result, item]` copies everything in `result` into a new array. Doing that once per item copies 1 element, then 2, then 3. For 10,000 items, that's about 50 million copied elements instead of 10,000 pushes. Objects built with `{ ...result, [key]: value }` cost the same.

The rule reports:

- In the callback of `reduce()` or `reduceRight()`: a spread of the first parameter, when the callback has exactly two parameters.
- In a loop: `result = [...result, item]` or `result = { ...result, ... }`, when `result` is a `let` declared outside the loop.

Change the accumulator in place instead. When the initial value is a fresh `[]` or `{}`, no other code holds it, so nothing else sees the change.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. To turn it on:

```toml bunfig.toml
[lint.rules]
"oxc/no-accumulating-spread" = "error" # or "warn"
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 2} */}
```js
const names = users.reduce((result, user) => [...result, user.name], []);

const byId = users.reduce((result, user) => ({ ...result, [user.id]: user }), {});
```

{/* bad */}
```js
let active = [];
for (const user of users) {
  if (user.isActive) {
    active = [...active, user];
  }
}
```

Not reported:

{/* good */}
```js
const names = users.map((user) => user.name);

const byId = users.reduce((result, user) => {
  result[user.id] = user;
  return result;
}, {});

const active = [];
for (const user of users) {
  if (user.isActive) {
    active.push(user);
  }
}
```

## When not to use it

For a handful of items, the cost doesn't matter. If you like how the spread reads and your lists are small, leave the rule off.
