Ship internal tools in hours, not weeks. Real auth, users, jobs, audit logs, and cohesive UI included. Early access $249 $499 → [Get it now]

How to remove duplicates from an array in JavaScript

Dealing with duplicate values in JavaScript arrays is a common issue, especially when working with data from APIs or user input where duplicate entries can occur unexpectedly. With over 25 years of experience in software development and as the creator of CoreUI, I’ve solved this problem countless times in production components like user lists, tag systems, and data aggregation features where clean, unique datasets are essential. From my extensive expertise, the most efficient and modern solution is to use the ES6 Set object together with the spread operator. This method is concise, reliable, and supported across all modern browsers while maintaining excellent performance.

Use Set with spread syntax to quickly remove duplicates from an array.

const numbers = [1, 2, 2, 3, 3, 4]
const unique = [...new Set(numbers)]

console.log(unique)
// [1, 2, 3, 4]

The Set constructor creates a new Set object containing only unique values from the array, automatically removing any duplicates. The spread operator ... then expands those unique values back into a new array. This method preserves the order of first occurrence, so the first instance of each value is kept while subsequent duplicates are discarded.

Why Set is the best choice

Set uses hash-based lookups internally, which means it runs in O(n) time — each element is checked once. Older approaches like filter() with indexOf() run in O(n²) because indexOf scans the array from the start for every element. For most real-world arrays, Set is both the cleanest and the fastest option.

// O(n) — preferred
const unique = [...new Set(items)]

// O(n²) — avoid for large arrays
const unique = items.filter((item, index) => items.indexOf(item) === index)

Removing duplicates from strings

Set works with any primitive type, including strings. This is useful when you need to deduplicate tags, categories, or user input.

const tags = ['react', 'javascript', 'react', 'vue', 'javascript']
const uniqueTags = [...new Set(tags)]

console.log(uniqueTags)
// ['react', 'javascript', 'vue']

The same O(n) performance applies here. Each string is compared by value, so identical strings are collapsed into a single entry while preserving the original order.

Removing duplicate objects by property

Set compares by reference, so it does not deduplicate objects with the same content. To remove duplicate objects based on a specific property, use a Map keyed by that property.

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 1, name: 'Alice' },
  { id: 3, name: 'Charlie' }
]

const uniqueUsers = [
  ...new Map(users.map(user => [user.id, user])).values()
]

console.log(uniqueUsers)
// [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }, { id: 3, name: 'Charlie' }]

The Map constructor accepts an array of [key, value] pairs. When two entries share the same key, the last one wins. Spreading .values() back into an array gives you a deduplicated list. This pattern is especially useful when working with API responses that may contain overlapping records.

Case-insensitive deduplication

When working with user-generated content, you may need to treat "React" and "react" as the same value. Normalize the values before inserting them into the Set.

const items = ['React', 'react', 'Vue', 'vue', 'Angular']

const seen = new Set()
const uniqueItems = items.filter(item => {
  const lower = item.toLowerCase()
  if (seen.has(lower)) return false
  seen.add(lower)
  return true
})

console.log(uniqueItems)
// ['React', 'Vue', 'Angular']

This approach keeps the first occurrence with its original casing while filtering out case-insensitive duplicates. The Set lookup remains O(1) per element, so the overall complexity stays at O(n).

Using Array.from instead of spread

You can also use Array.from() as an alternative to the spread operator. Both produce the same result — choose whichever reads better in your codebase.

const numbers = [1, 2, 2, 3, 3, 4]
const unique = Array.from(new Set(numbers))

console.log(unique)
// [1, 2, 3, 4]

Array.from() accepts any iterable, including Set, Map, and NodeList. This makes it a versatile utility beyond just deduplication.

Best Practice Note:

This is the same approach we use in CoreUI components to ensure clean and predictable data. The CSmartTable component relies on unique identifiers when rendering rows, so deduplicating data before passing it as items prevents rendering issues and key collisions.

For primitive values, always reach for Set first — it is the fastest and most readable option. Only use Map or filter with custom logic when you need to deduplicate objects by a specific property.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to show or hide elements in React? A Step-by-Step Guide.
How to show or hide elements in React? A Step-by-Step Guide.

How to return multiple values from a JavaScript function
How to return multiple values from a JavaScript function

How to loop inside React JSX
How to loop inside React JSX

How to validate an email address in JavaScript
How to validate an email address in JavaScript

Answers by CoreUI Core Team