How to convert a string to a boolean in JavaScript

The reason this question has 111 answers is one line:

Boolean("false") = true

Every non-empty string is true

Boolean("true"     ) = true
Boolean("false"    ) = true
Boolean("0"        ) = true
Boolean(""         ) = false
Boolean(" "        ) = true
Boolean("null"     ) = true

Boolean() is not a parser. It asks whether the value is truthy, and every string except "" is. "false", "0" and even a single space all come back true.

The two other spellings behave the same, because they are the same thing:

!!"false"      : true
if ("false")   : taken

Comparing to the string

cmp("true") = true   cmp("TRUE") = false   cmp("1") = false

s === "true" is the accepted answer and it is correct as far as it goes. Note what it decides for you: "TRUE" is false, and so is "1". If your input comes from a config file or a checkbox, that may well be wrong.

One toLowerCase() and a trim() fix the obvious part:

cmp2(" True ") = true

JSON.parse, and why not

JSON.parse("true" ) = true  (boolean)
JSON.parse("1"    ) = 1  (number)
JSON.parse("yes"  ) throws: SyntaxError: Unexpected token 'y', "yes" is not valid JSON
JSON.parse(""     ) throws: SyntaxError: Unexpected end of JSON input
JSON.parse("TRUE" ) throws: SyntaxError: Unexpected token 'T', "TRUE" is not valid JSON

Two problems. JSON.parse returns the number 1 for "1", not a boolean — so typeof lies to whatever comes next. And it throws on anything that is not JSON, including the empty string, which is a realistic value for a missing form field.

Where these strings come from

a="true"   Boolean=true  ==="true"=true
b="false"  Boolean=true  ==="true"=false
c="0"      Boolean=true  ==="true"=false
d=""       Boolean=false ==="true"=false

That is a ?a=true&b=false&c=0&d= query string read back with URLSearchParams. A URL has no types. ?b=false arrives as the string "false", which is truthy, which means the opposite of what the person writing the URL intended.

localStorage does the same thing: store false, read back "false". Same for a data- attribute, a .env file and most database drivers’ TEXT columns.

Non-strings arrive too

[]   Boolean=true  ==="true"=false ==true=false
{}   Boolean=true  ==="true"=false ==true=false
"0"  Boolean=true  ==="true"=false ==true=false

[] == true is false while Boolean([]) is true. Whatever intuition you have about ==, it does not survive contact with this table — don’t use it here.

A converter that decides

const toBool = (v, dflt = false) => {
  if (typeof v === "boolean") return v;
  const s = String(v).trim().toLowerCase();
  if (["true", "1", "yes", "on"].includes(s)) return true;
  if (["false", "0", "no", "off", ""].includes(s)) return false;
  return dflt;
};
toBool("true")=true   toBool("TRUE")=true   toBool(" on ")=true   toBool("1")=true
toBool("false")=false toBool("0")=false     toBool("no")=false    toBool("")=false
toBool("banana")=false  toBool(true)=true   toBool(null)=false

The last row is the point. "banana" is not a boolean, and something has to happen — a default you chose and can see, rather than true because the string happened to be non-empty.

Which strings belong in each list is your decision, not JavaScript’s. Write it down where the next person can read it.

About Netcup (advertisement)

The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).