Of course a counter argument is that you don’t usually swap C compilers between projects and libc is stable af, but if a toolchain and/or stdlib was constantly changing and subject to non-compat, you’d have to.
The compiled JS is hundreds of bytes at most, usually because React creates a bunch of boilerplate for you (a basic CSS file, an application, a web worker, etc) which you may remove.
(Obviously, that's neither here or there when we're talking about baselines for SPAs)
The actual languages are often Typescript and jsx, to say nothing of the Svelte compiler or Elm.
You can write vanilla JS without all that, of course.
And of course, this basic explanation doesn’t really do justice to answering your question, because depending on your definition of what a “character” is, you may need to take into account ligatures etc.
Given the nature of the questions, I presumed they were interested in knowing “how does JavaScript load strings into memory, anyway?”
And to answer that question, your rough heuristic should be “2 bytes per character” not 1, even for ascii range. That just leads to additional questions, though, because of the oddity of it.
In order to achieve the ability to do Unicode, there’s a reserved set of values within that 2-bytes, to allow you to extend the encoding to reach Unicode.
Back to the original measurement, for the string “hello world”, I believe a JavaScript `sizeof`, if it existed, would report 24 bytes (22 for the characters, and 2 (give or take) for either the NULL character or for a length header.
See this[0] for reference. Note how the first byte must fall within a certain range in order to signal being a surrogate pair. This range quite deliberately falls outside the ASCII range. This fact is taken advantage of by JS parsers to make parsing of ASCII substrings faster by special casing that range, since checking for a valid character in the entire unicode range is quite a bit more expensive[1].
IMHO nitpicking about memory consumption of the underlying data structure is a bit meaningless, since the spec doesn't actually enforce any guarantees about memory layout. An implementation can take more memory for pointer to prototype, to cache hash code/length, etc, and there are also considerations such as whether the underlying data structure is polymorphic or monomorphic due to JIT, whether the string is boxed/unboxed, whether it's implemented in terms of C strings vs slices, etc.
Regardless, it doesn't change the fact that the octet sequence "hello world" takes 11 bytes in ASCII/UTF8 encoding (disregarding implementation metadata).
[0] https://github.com/jquery/esprima/blob/0911ad869928fd218371b...
[1] https://github.com/jquery/esprima/blob/0911ad869928fd218371b...