In NodeJS for example don't you have use Buffers and special decoders to deal with UTF-8 strings? I.e it's a pain there too.
> '蛋糕'.substr(0,1)
'蛋'
> '蛋糕'.length
2
> Buffer.byteLength('蛋糕')
6
You do have to be careful when working with binary data (e.g. streams) but this is expected.It just so happens that your example consists of two UTF-16 codepoints.
(Node.js' Buffer uses UTF-8 by default).
> '𐐩'.substr(0, 1)
'\ud801'
> '𐐩'.length
2
[1] https://en.wikipedia.org/wiki/UTF-16#Description