Why it made sense
Accepting HTML strings everywhere made jQuery delightfully terse, and deep $.extend was the obvious way to merge plugin options with user settings.
What changed
CVE-2020-11022 and CVE-2020-11023 showed that passing untrusted HTML to methods like .html() and .append() could execute script even after sanitising (fixed in 3.5.0). CVE-2019-11358 showed that $.extend(true, {}, untrustedJson) could modify Object.prototype (fixed in 3.4.0). The fixes are years old, but sites that pinned older versions still ship the vulnerable code, and the underlying habit — building HTML from strings — remains.
What jsKjs does instead
jsKjs makes the safe option the short one: .text() and kj-text for user content, $.escape() when you must build HTML, and server-rendered fragments for Hyper. Deep $.extend skips __proto__, constructor and prototype keys.
Full disclosure: our own pre-release $.extend had exactly this prototype-pollution bug. We found it in review before launch, fixed it, and added a regression test. One more caveat: Pulse evaluates expressions with new Function, so strict Content-Security-Policies need 'unsafe-eval' on pages that use kj-data — the same trade-off as Alpine's standard build.
jQuery
$('#greeting').html('Hello ' + params.get('name')); // XSS
$.extend(true, settings, JSON.parse(userJson)); // pre-3.4: prototype pollutionjsKjs
$('#greeting').text('Hello ' + params.get('name')); // always text
$('#card').html('<b>' + $.escape(name) + '</b>'); // escaped when building HTML
$.extend(true, settings, JSON.parse(userJson)); // __proto__ keys are ignored