All offsets and text lengths in ProseMirror are counted in utf16 code units, by design (mostly because it would be painfully expensive to do otherwise). So yes, not hitting the middle of surrogate pairs (or, in most circumstances, multi-codepoint glyphs) when doing something like inserting content is the responsibility of the caller. You’ll usually work with selection or node positions anyway, which should already be in valid places, but if you’re computing positions otherwise you have to be somewhat careful about this.