Replace chunks of whitespace with a single spaces

Quick Take

import { strict as assert } from "assert";
import { collapse } from "string-collapse-white-space";

  collapse("  aaa     bbb    ccc   dddd  ").result,
  "aaa bbb ccc dddd"

  collapse("   \t\t\t   aaa   \t\t\t   ").result,

  collapse("   aaa   bbb  \n    ccc   ddd   ", {
    trimLines: false,
  "aaa bbb \n ccc ddd"

  collapse("   aaa   bbb  \n    ccc   ddd   ", {
    trimLines: true,
  "aaa bbb\nccc ddd"

// \xa0 is an unencoded non-breaking space:
    "     \xa0    aaa   bbb    \xa0    \n     \xa0     ccc   ddd   \xa0   ",
    { trimLines: true, trimnbsp: true }
  "aaa bbb\nccc ddd"



collapse(str, [opts])

In other words, it's a function which takes two input arguments, second-one being optional (marked by square brackets).

API - Input

Input argument Type Obligatory? Description
str String yes Source string to work upon
opts Something falsy or a Plain object no The Optional Options Object, see below for its API

API - Output

Function returns a plain object, for example:

result: "abc click me def",
ranges: [
[3, 6, " "],
[14, 18, " "],

It has the following keys:

Key's name Key value's type Description
result String The string output where all ranges were applied to it.
ranges ranges: an array of one or more arrays containing from-to string index ranges OR null For example, if characters from index 0 to 5 and 30 to 35 were deleted, that would be [[0, 5], [30, 35]]. Another example, if nothing was found, it would put here null.

Optional Options Object

opts is a plain object. Here are all its keys:

options object's key Type Obligatory? Default Description
trimStart Boolean no true if false, leading whitespace will be just collapsed.
trimEnd Boolean no true if false, trailing whitespace will be just collapsed.
trimLines Boolean no false if true, every line will be trimmed (all whitespace characters except line breaks CR and LF will be deleted, also non-breaking spaces will be deleted, if trimnbsp is set to true)
trimnbsp Boolean no false when trimming, do we delete non-breaking spaces (if set to true, answer would be "yes"). This setting also affects trimLines setting above.
removeEmptyLines Boolean no false if any line can be trimmed to empty string, it will be removed.
limitConsecutiveEmptyLinesTo Natural number or zero no 0 Set to 1 or more to allow that many blank lines between content
enforceSpacesOnly Boolean no false If enabled, not only consecutive space character chunks will be collapsed but any whitespace character chunks (except line breaks).
cb Function no see below All output and every whitespace chunk (including single spaces) is fed to it. Whatever you return, gets written to resulting ranges.

Here is the Optional Options Object in one place (in case you ever want to copy it whole):

trimStart: true,
trimEnd: true,
trimLines: false,
trimnbsp: false,
removeEmptyLines: false,
limitConsecutiveEmptyLinesTo: 0,
enforceSpacesOnly: false,
cb: ({ suggested, whiteSpaceStartsAt, whiteSpaceEndsAt, str }) => suggested,


This program implements a callback interface - every reported range is fed to the callback. The default callback is ({ suggested }) => suggested but you can tweak it.

See examples.

When nothing is to be removed, callback will ping suggested key value as null. You can still return any string index range and it will be deleted (array of two elements) or replaced (array of three elements). Learn more about ranges notation.


See it in the monorepo opens in a new tab, on GitHub.


To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.


MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 detergent 8.0.1
Extracts, cleans and encodes text
📦 string-remove-widows 3.0.1
Helps to prevent widow words in a text
📦 string-fix-broken-named-entities 6.0.1
Finds and fixes common and not so common broken named HTML entities, returns ranges array of fixes
📦 string-extract-sass-vars 3.0.1
Parse SASS variables file into a plain object of CSS key-value pairs
📦 string-trim-spaces-only 4.0.1
Like String.trim() but you can choose granularly what to trim
📦 string-left-right 5.0.1
Looks up the first non-whitespace character to the left/right of a given index
📦 string-overlap-one-on-another 3.0.1
Lay one string on top of another, with an optional offset