Skip to content

Instantly share code, notes, and snippets.

View jimmywarting's full-sized avatar

Jimmy Wärting jimmywarting

View GitHub Profile
@jimmywarting
jimmywarting / The Web is Being Hijacked — And We’re All Stuck in Chrome.md
Last active June 22, 2025 17:03
The Web is Being Hijacked — And We’re All Stuck in Chrome

I used to be a huge Firefox nerd before chrome become mainstream. I loved how it fought for better, cleaner, more bug-free web standards. I believed in the open web — a place where everyone could build, compete, and innovate fairly. Safari impressed me with its speed, efficiency, and privacy focus and macOS integration.

But today? I’m stuck. Stuck in Chrome.

Why? Because Chrome has become the new Internet Explorer. The browser that sets its own rules, forces everyone else to follow, and drags the entire web down its own rabbit hole.


Chrome’s Chromium Monopoly Is the Worst Kind of Vendor Lock-in

@jimmywarting
jimmywarting / toSafeNode.md
Last active March 23, 2025 07:57
html to safe node (document)

This is for when you are building a library and csp are in the way and require you to use trustedTypes html

var toSafeNode=(h,x=new XMLHttpRequest)=>(x.send(x.open('GET',URL.createObjectURL(new Blob([h])),0)),x.responseXML)
var fragment = toSafeNode('<div>hej</div>')
@jimmywarting
jimmywarting / readme.md
Created March 7, 2025 21:19
Allow http/2 (h2) with native fetch in node
// https://github.com/nodejs/undici/issues/2750#issuecomment-2707472553

// undici global symbol are lazy loaded, so we need to trigger it first
try { fetch('data:;base64,') } catch (e) { }

// Get the global agent
const unidiciGlobalDispatcherSymbol = Symbol.for('undici.globalDispatcher.1');
const agent = globalThis[unidiciGlobalDispatcherSymbol]
@jimmywarting
jimmywarting / cjs-in-esm.md
Last active January 27, 2024 18:02
using cjs in esm runtime (NodeJS)
@jimmywarting
jimmywarting / block-reader.js
Last active January 25, 2024 13:15
Memory efficient block reader of fetch- `Response.body` a.k.a `RedableStream`
/**
* Read a stream into same underlying ArrayBuffer of a fixed size.
* And yield a new Uint8Array view of the same underlying buffer.
* @param {ReadableStreamBYOBReader} reader
* @param {number} chunkSize
*/
async function* blockReader(reader, chunkSize) {
let offset = 0;
let buffer = new ArrayBuffer(chunkSize)
let done, view
@jimmywarting
jimmywarting / reload.js
Last active February 20, 2024 21:13
Simple dependency free file auto-reload (NodeJS)
import { watch } from 'node:fs/promises'
import { Worker } from 'node:worker_threads'
let worker = new Worker('./app.js')
async function reloadOnChange (dir) {
const watcher = watch(dir, { recursive: true })
for await (const change of watcher) {
if (change.filename.endsWith('.js')) {
worker.terminate()
@jimmywarting
jimmywarting / mod.js
Last active February 20, 2024 21:13
Reading a blob synchronous in javascript
const blob = new Blob(['123'])
const xhr = new XMLHttpRequest()
const url = URL.createObjectURL(blob)
// required if you need to read binary data:
xhr.overrideMimeType('text/plain; charset=x-user-defined')
xhr.open('GET', url, false)
xhr.send()
const uint8 = Uint8Array.from(xhr.response, c => c.charCodeAt(0))
  • ⎋ (escape): U+238B
  • ⇥ (tab): U+21E5
  • ⇪ (caps lock): U+21EA
  • ⇧ (shift): U+21E7
  • ⌃ (control): U+2303
  • ⌥ (option): U+2325
  •  (Apple): U+F8FF (in some Apple-provided fonts only)
  • ⌘ (command): U+2318
  • ␣ (space): U+2423
@jimmywarting
jimmywarting / README.md
Last active February 1, 2025 04:11
Create your own archive format with just 60 lines of javascript

# Create Your Own Archive Format with Just 60 Lines of JavaScript

Table of Contents

  • Explanation (Introduction, Why & How)
  • Browser Limitations (Memory, Streaming, Writing, Uploading)
  • What are Blobs? (How Do They Work?)
  • The Solution (Code Sample)
    • How to Use the Sample Code
  • Takeaways (Reflection)
@jimmywarting
jimmywarting / example.js
Created February 18, 2020 12:43
native (de)compress in browser
import { compress, decompress } from 'zlib.js'
compr = await compress('hhhhheeeej'.repeat(200)).blob()
blob = await decompress(compr).blob()