Paste one item per line and run the tool. Lines are compared as entered, so differences in case or spacing remain significant.
Runs locally in your browserPaste one item per line and press Remove duplicate lines. The first occurrence of each line stays where it was and later copies are dropped, so the result keeps the original order instead of sorting it.
The comparison is exact: “Apple” and “apple” are two different lines, and so are “apple” and “apple ” with a trailing space. Three checkboxes under the box loosen that rule when the list was assembled from different sources.
Every line is compared as it was typed, character by character. Case counts (“Total” and “total” are different lines), a trailing space counts, and two lines that look identical can still differ: a no-break space (U+00A0) instead of a normal space, or an accent written as a separate combining character instead of one code point, both keep the lines apart. That is why a list copied from a web page or a PDF sometimes keeps a “duplicate” the eye cannot see.
Blank lines count as content too. A run of blank lines collapses to a single blank line, and a list that ends with a line break is treated as ending with its last item: the break itself no longer adds an empty line to the result, as the earlier version of this page did.
Ignore case compares lower-cased lines. Ignore spaces at line edges trims each line and collapses runs of spaces (tabs included) inside it to one space, so “ JS tools ” matches “js tools”. Remove blank lines drops empty lines from the result. The line that is kept is always the first one as written, never the normalised form.
“Lines in / Removed / Lines out” reports what happened: lines in counts the lines that were read (a trailing line break is not counted), Removed counts every line the run dropped, and Lines out counts the lines that remain. The output is plain text, ready to paste into a spreadsheet column, an SQL IN list or a code array.
The tool runs in this browser: the text is read from the box, deduplicated locally and rendered again, and nothing is uploaded. Measured on this build with real Chrome: no request leaves the page while a list is processed.
Output longer than 50,000 characters is printed without syntax colours, because the shared highlighter stops there; the text itself is unchanged. Lines whose value happens to be a JavaScript object property name — toString, constructor, valueOf, hasOwnProperty, __proto__ and the rest — used to be deleted by the older version even when they appeared once. This build keeps them, which is one reason the counts can differ from what the page returned before.