Mathias Bynens
mathiasbynens.be · Personal blog · on HN since 2010
Mathias Bynens, a web developer and JavaScript engine contributor, writes about Unicode, JavaScript internals, and web standards.
What HN saysHN commenters link his URL validation regex demo, his JavaScript Unicode essays, and his globalThis notes, calling them worth saving.
123HN people shared it
74linked it in comments
94stories submitted
1.8Kstory points
5 months agolast shared
2010people per year2026
Most-shared posts
- 1How to support full Unicode in MySQL databases13 people · 28 points · first shared 2012 · 6 comments on HN
- 2Visualization of jQuery file size over the years13 people · 1 points · first shared 2010 · discussion on HN
- 3JavaScript has a Unicode problem (2013)12 people · 91 points · first shared 2013 · 35 comments on HN
- 4JavaScript’s internal character encoding: UCS-2 or UTF-16?11 people · 37 points · first shared 2012 · 15 comments on HN
- 5JavaScript Engine Fundamentals: Shapes and Inline Caches9 people · 90 points · first shared 2018 · 8 comments on HN
- 6In search of the perfect URL validation regex (2010)7 people · 318 points · first shared 2014 · 81 comments on HN
- 7A horrifying globalThis polyfill in JavaScript7 people · 169 points · first shared 2019 · 73 comments on HN
- 8Valid JavaScript variable names7 people · 91 points · first shared 2012 · 39 comments on HN
- 9Asynchronous stack traces: why await beats .then() – Mathias Bynens6 people · 10 points · first shared 2017 · discussion on HN
- 10ECMAScript regular expressions are getting better (2017)5 people · 155 points · first shared 2017 · 103 comments on HN
- 11ES6 const is not about immutability5 people · 11 points · first shared 2016 · 1 comments on HN
- 12Using CSS without HTML4 people · 126 points · first shared 2012 · 25 comments on HN
- 13The smallest possible valid (X)HTML documents4 people · 82 points · first shared 2011 · 1 comments on HN
- 14Helpful infornmation about touch icons (2011)4 people · 7 points · first shared 2011 · 1 comments on HN
- 15Optimizing the asynchronous Google Analytics snippet · Mathias Bynens4 people · 5 points · first shared 2010 · discussion on HN
What HN people wrote when they linked it
zsims · 2023-09-07
It's from https://mathiasbynens.be/demo/url-regex and rather fantastic. Thanks for sharing
wruza · 2022-01-10
It depends. Bare hash tables are semi-random and get reshuffled at growth points naturally. But I remember reading in some manual that that language reshuffles iteration even for immutable hash tables. Js objects are usually based on "shapes", which do not follow hash table semantics:
https://mathiasbynens.be/notes/shapes-ics
https://v8.dev/blog/fast-properties
tempodox · 2020-06-17
This looks like it's worth a place in an electronic bookshelf. Among other things, following a link in the contents led me to this little pearl: https://mathiasbynens.be/notes/globalthis
devy · 2015-11-11
In my own experience, the biggest unicode implementation failure was MySQL's choice of using 3-byte BMP Only UTF-8 instead of a full 4-byte Unicode support.[1] In retrospect, their decision to go with a broken subset implementation had caused more trouble, confusions and incompatibilities than their claimed benefits of speed/performance/simplification. Do a simple google search will see almost everyone recommends avoid `utf8` and use `utf8mb4` instead. [2][3][4]
As a result, if your MySQL databases/tables/columns are using `utf8` instead of `utf8mb4` (a MySQL invention) charset, you cannot store / retrieve emoji characters properly.
[1] https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html
[2] https://mzsanford.wordpress.com/2010/12/28/mysql-and-unicode/
[3] https://mathiasbynens.be/notes/mysql-utf8mb4
[4] https://www.drupal.org/node/1314214
mathias · 2014-02-12
Excellent point. I was aware http://mathiasbynens.be/notes/javascript-unicode#accounting-for-other-… is not a fully accurate/bulletproof solution (never said it was, either). I’ve added a note to the article now, linking to UAX#29. Thanks!
adev_ · 2020-05-24
> If it's really common for everything to become a performance bottleneck, it's worth profiling from the start so that you avoid having major pitfalls anywhere. If it's rare and exceptional, FFI for those cases is fine.
You can have it both way, code evolve. It is pretty common in performance critical code that a minor, almost never call function in one scenario, become a performance critical bottleneck in an other. If you already played with large scaled simulation software, this happened almost every week depending of your inputs on what you are interested to simulate.
> On the contrary. Plenty of people do those kind of things in, say, Java. They require knowing about compiler internals and using unsupported hints, or even bypassing parts of the compiler
No it's not again. I have been developing in C++ for 15 years, including in the HPC world and I (close to) never had to touch a compiler internal.
The language gives you what you need for performances, you do not need to play with that.
At the opposite JIT compilers like V8 or Java are monster of complexity very sensible to side effect [1] and controlling things like "Does this data fit in my L2 cache ?" in them is close to impossible because even things like "Where are my data and what are there size ?" is an hard question.
Once again, there is theory and there is practice.
Theory is what you say. Practice is that 98% of performance critical software in HPC, game industry, physics and High Frequency Trading is in…
Stratoscope · 2019-12-07
Both of your examples have invalid sort comparator functions.
A JavaScript sort comparator is required to not only return a positive or negative value, it must handle all three cases: greater than, less than, or equal. When the arguments compare equal, the comparator must return 0.
Returning only a positive or negative value is a very common error. (I don't mean to pick on you for this! I have seen the error so often that I hope this may be helpful for anyone writing a sort comparator.)
The invalid comparator will force the normally stable sort to be unstable, because sort() now has no way to know that two items should be considered equal and their existing order preserved.
Let's demonstrate with the "doggos" example that the article links to:
https://mathiasbynens.be/demo/sort-stability
The code starts with this array:
const doggos = [
{ name: 'Choco', rating: 12 },
{ name: 'Devlin', rating: 13 },
{ name: 'Eagle', rating: 13 },
{ name: 'Jenny', rating: 13 },
{ name: 'Kona', rating: 13 },
{ name: 'Leila', rating: 13 },
{ name: 'Milly', rating: 14 },
{ name: 'Molly', rating: 12 },
{ name: 'Nova', rating: 12 },
{ name: 'Oliver', rating: 13 },
{ name: 'Patches', rating: 14 },
];
It uses this valid comparator:
doggos.sort( ( a, b ) => b.rating - a.rating );
(Note that this implements a reverse sort as can be seen in the output on the test page.)
Subtraction provides the proper…
soanvig · 2026-06-20
Honestly it didn't interest me, but I do remember from back in the days full websites rendered by a browser from... Empty files. https://mathiasbynens.be/notes/css-without-html
osmsucks · 2025-08-02
JavaScript is: https://mathiasbynens.be/notes/javascript-encoding
andrewstuart · 2024-08-13
What about animated PNG?
https://apng.onevcat.com/demo/
Or animated webp?
https://mathiasbynens.be/demo/animated-webp
https://cobalt.googlesource.com/cobalt/+/refs/tags/trunk.unnest/cobalt…
egypturnash · 2024-03-23
Previous work in this field:
https://mathiasbynens.be/demo/css-without-html - completely empty html, doesn't seem to work on Mac Safari any more, does work on Firefox for me. See https://css-tricks.com/using-css-without-html/ if you want to know how it works.
https://web.archive.org/web/20160420232319/cj-johnson.github.io/Single… (original copy defunct) - kinda broken now, the source is just a single <link> (if you ignore all the stuff the Wayback Machine adds)
night-rider · 2023-07-25
It's not that it's hard, it's just people don't go out of their way to escape UTF-8 glyphs into ASCII when dealing with exotic glyphs in a text editor. It's more mundane and tedious, but not 'hard'.
Try working with raw UTF-8 in JS and find yourself in a world of pain. Mathias Bynens talks about these gotchas here:
https://mathiasbynens.be/notes/javascript-unicode
nirvdrum · 2023-05-06
I found [1] to be a pretty good summary of the key concepts that support the claim. The article, unfortunately, doesn't come right out and say it. But, it talks about how object shapes (a common JS object model) can be used as guards for inline caches (IC) to generate efficient machine code for property access. If you add a new property, you change the shape, which causes the cache guard to fail. That leads to deoptimization since the assumptions made about the call site when the code was compiled no longer hold. That call site is now either polymorphic or megamorphic, depending on the type of IC used and its level of polymorphism.
[1] -- https://mathiasbynens.be/notes/shapes-ics
fwip · 2022-08-01
I got curious and looked it up, looks like Jquery is about 30kb compressed & minified nowadays: https://mathiasbynens.be/demo/jquery-size
wereHamster · 2022-06-26
> UTF-16 is mostly a “worst of both worlds” compromise at this point, and the main programming language I can think of that uses it (and exposes it in this form) is Javascript, and that too in a broken way.
Unicode predates JavaScript. JS use UCS-2!
From https://mathiasbynens.be/notes/javascript-encoding
JavaScript engines are free to use UCS-2 or UTF-16 internally. Most engines that I know of use UTF-16, but whatever choice they made, it’s just an implementation detail that won’t affect the language’s characteristics.
The ECMAScript/JavaScript language itself, however, exposes characters according to UCS-2, not UTF-16.
mananaysiempre · 2022-02-08
As the continuation bytes always bear the payload in the low 6 bits, Connor Lane Smith suggests writing them out in octal[1]. Though that 3 octets of UTF-8 precisely cover the BMP is also quite convenient and easy to remember (but perhaps don’t use that like MySQL did[2]?..).
[1] http://www.lubutu.com/soso/write-out-unicode-in-octal
[2] https://mathiasbynens.be/notes/mysql-utf8mb4
kerblang · 2022-01-12
The author of original article links to this one in their post:
https://mathiasbynens.be/notes/mysql-utf8mb4#utf8-to-utf8mb4
And yeah, there's gotchas in there, the main one being that strings that barely fit now won't fit, and also maximum lengths on indexable strings.
inglor · 2022-01-02
Parsing JSON is tricky, you need to figure out the structure as you go. JavaScript implementations can reuse their JIT machinery to figure out the structure of parsed JSON (here's shapes if you're not familiar https://mathiasbynens.be/notes/shapes-ics )
You _can_ do it outside the engine but it'd be tricky and you'd have to either write a lot of code _or_ to trick the engine to reuse the JIT machinery for your parser.
Protocols with schemas are much much easier to parse efficiently so I suspect it'd be as fast in library written JS.
layoutIfNeeded · 2021-07-01
False. JavaScript uses UTF16: https://mathiasbynens.be/notes/javascript-encoding
remexre · 2021-06-20
Taking a look at that, I think shapes would still work; [1] has some background material on them, but dynamically changing data is what shapes are for; you check if you should update an object's shape when assigning to it, and can JIT based on the type (you ought to be able to handle getattr and setattr with this too, JITting to a direct call to that method when it's necessary). Where this completely falls down in optimizing Python is that it changes the object layout, so you can't pass these to CPython without making them generic and converting them back after. Converting the layout to be generic would be a deep copy (which of course is semantics-breaking), converting it back wouldn't even be possible if the C code kept a reference to it around.
[1]: https://mathiasbynens.be/notes/shapes-ics
callen43 · 2021-06-08
I almost get the impression that the only single restriction to urls is having http(s):// at their beginning.
Also reminds me on this interesting collection of unusual urls (and regular expressions)
https://mathiasbynens.be/demo/url-regex
crazypython · 2021-02-23
Nuitka only removes interpreter overhead. (just 30%) It's still quite slow. To get real performance improvements, we'd need memory optimizations such as a modern JIT's hidden classes and shapes, which store data directly on the object, instead of inside a dictionary. https://mathiasbynens.be/notes/shapes-ics
Ajedi32 · 2020-08-11
Yeah benchmarks can be much more difficult to get right than it might seem at first glance. Good thing they didn't try to write their own benchmarking code, otherwise they might have fallen into those traps you just mentioned.
Luckily, they didn't, and instead pulled in the the `benchmark` library as a development dependency[1]. The author of said library works on V8, and already considered all those problems and much, much, more[2].
[1]: https://github.com/left-pad/left-pad/blob/master/perf/perf.js
[2]: https://mathiasbynens.be/notes/javascript-benchmarking
erik_seaberg · 2020-03-29
This. Javascript engines have to do stuff like https://mathiasbynens.be/notes/shapes-ics to assume many objects will have the same key names and types and create an optimized class layout, with some kind of expensive fallback if anyone ever randomly stores a key or value that violates the assumption. They can't even be sure you'll always be doing integer math (unless you resort to bit masking a la asm.js). Hinting (like __slots__ in Python) might have helped some.
Izkata · 2019-10-01
Screw it, let's abandon all markup and content: https://mathiasbynens.be/demo/css-without-html
(Explanation: https://css-tricks.com/using-css-without-html/ )
robocat · 2019-06-30
JavaScript has virtually always supported Unicode variable names (well, the basic multilingual plane).
https://mathiasbynens.be/notes/javascript-identifiers
mynameisvlad · 2019-02-13
JQuery Minified and GZipped is also 30KB: https://mathiasbynens.be/demo/jquery-size
When doing comparisons, don't be disingenuous. Compare like numbers.
mschuster91 · 2019-02-12
> It's one less network request, saves bandwidth
Given that most stuff these days is packed together with Webpack or at least concat'd together, you don't really save much, plus jQuery in gzip'd form is clocking in at <30 kB anyway (https://mathiasbynens.be/demo/jquery-size).
> and pretty much unmaintained code (at this point, the jQuery github is as good as dead, unlikely to see major releases any time soon)
So what? Software can very well be "done", there is no need to always evolve and evolve. As long as there is no security issue left unsolved, though.
In addition, if you're rebuilding half of it on your own anyway, chances are high you'll miss some weird corner case that jQuery solved years, or decades, ago.
ancarda · 2018-12-14
That may not be enough -- the connection also has to be utf8mb4 as well as other settings: https://mathiasbynens.be/notes/mysql-utf8mb4
I have no idea if JIRA supports configuring every aspect of setting up a MySQL connection.
cpeterso · 2018-12-13
public and private are already reserved keywords in JavaScript strict mode, so there should be no issue with web compatibility.
https://mathiasbynens.be/notes/reserved-keywords