# JavaScript code review checklist

> JavaScript code review checklist of the mistakes Revix flags in real pull requests, from errors matched by message text to large array spreads.

Canonical URL: https://www.revix.ai/checklists/javascript

JavaScript code review misses quiet bugs in error handling, arrays and dates. This checklist covers the mistakes Revix flags in real pull requests. Look for errors checked by message text, large arrays spread into one call, and errors rethrown without their original cause. Each rule shows the code to flag, the fix and its source.

Author: Oscar Estudillo · Updated: 2026-10-30

## 12 rules to check in every JavaScript pull request

### Do not discriminate errors by parsing messages

Error messages are descriptive text and can be similar across different failures; the documentation recommends error cause for discriminating errors emitted by a library.

**Avoid**

```javascript
if (err.message === "Not found") handleMissing();
```

**Prefer**

```javascript
if (err instanceof NotFoundError) handleMissing();
```

Flagged by Revix in real reviews · Best practice · All current versions · Source: [Error - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)

### Avoid spreading large arrays into Math.max

Argument-list expansion is constrained by the runtime's maximum number of function arguments, while reduction processes the array without expanding it.

**Avoid**

```javascript
const highest = Math.max(...unboundedValues);
```

**Prefer**

```javascript
const highest = unboundedValues.reduce((a, b) => Math.max(a, b), -Infinity);
```

Flagged by Revix in real reviews · Performance · All current versions · Source: [Math.max() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max)

### Use structuredClone for JSON-free deep copies

The JSON representation cannot preserve all JavaScript object graphs or value types.

**Avoid**

```javascript
const copy = JSON.parse(JSON.stringify(value));
```

**Prefer**

```javascript
const copy = structuredClone(value);
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [JSON.stringify() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify)

### Preserve the original error when wrapping

The documented cause property preserves the reason for the new error and makes the original error and stack trace available to higher-level handlers.

**Avoid**

```javascript
catch (err) { throw new Error("Request failed"); }
```

**Prefer**

```javascript
catch (err) { throw new Error("Request failed", { cause: err }); }
```

Flagged by Revix in real reviews · Best practice · All current versions · Source: [Error - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)

### Use RangeError for invalid argument ranges

RangeError semantically represents an argument that is not within the function's permitted range or set of values, making the failure distinguishable to callers.

**Avoid**

```javascript
if (n < -500 || n > 500) throw new Error('out of range');
```

**Prefer**

```javascript
if (n < -500 || n > 500) throw new RangeError('out of range');
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [RangeError - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RangeError)

### Handle malformed URI escapes

Malformed URL data can otherwise cause an uncaught exception and interrupt the surrounding operation.

**Avoid**

```javascript
const value = decodeURIComponent(req.query.value);
```

**Prefer**

```javascript
let value;
try { value = decodeURIComponent(input); } catch (e) { rejectInput(); }
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [URIError: malformed URI sequence - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Malformed_URI)

### Do not rely on toString tags for type detection

Objects can define or inherit Symbol.toStringTag and thereby produce an unexpected tag, making class detection with Object.prototype.toString() unreliable.

**Avoid**

```javascript
if (Object.prototype.toString.call(value) === "[object Date]") useDate(value);
```

**Prefer**

```javascript
if (value instanceof Date) useDate(value);
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [Object.prototype.toString() - Using toString() to detect object class](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/toString)

### Release stream reader locks

A forgotten lock prevents another reader from consuming the stream and can cause a TypeError when later code calls getReader().

**Avoid**

```javascript
const reader = stream.getReader();
const chunk = await reader.read();
return chunk;
```

**Prefer**

```javascript
const reader = stream.getReader();
try { return await reader.read(); } finally { reader.releaseLock(); }
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [JavaScript resource management](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Resource_management)

### Avoid reversing a copy to find the last match

Reversing or copying an array adds allocation and traversal overhead that findLast() avoids.

**Avoid**

```javascript
[...tasks].reverse().find(task => task.completed)
```

**Prefer**

```javascript
tasks.findLast(task => task.completed)
```

Flagged by Revix in real reviews · Performance · All current versions · Source: [Array.prototype.findLast() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLast)

### Check findIndex() against -1

JavaScript treats 0 as falsy and -1 as truthy, so a direct conditional on the returned index produces incorrect control flow.

**Avoid**

```javascript
if (items.findIndex(isMatch)) handle(items);
```

**Prefer**

```javascript
if (items.findIndex(isMatch) !== -1) handle(items);
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [Array.prototype.findIndex() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex)

### Do not use toISOString for local time

The method converts the value to universal time rather than preserving the host's local timezone.

**Avoid**

```javascript
const displayed = date.toISOString(); // expected local time
```

**Prefer**

```javascript
const displayed = date.toLocaleString();
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [Date.prototype.toISOString() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)

### Treat getTime() values as milliseconds

A unit mismatch can produce timestamps that are off by a factor of 1,000 while still looking like valid numbers.

**Avoid**

```javascript
const expiresAt = new Date().getTime();
setTimeoutAt(expiresAt); // expects seconds
```

**Prefer**

```javascript
const expiresAt = Math.floor(Date.now() / 1000);
setTimeoutAt(expiresAt);
```

Flagged by Revix in real reviews · API usage · All current versions · Source: [Date.prototype.getTime() - JavaScript | MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime)
