Surma
@surma.dev
DX at Shopify. Web Platform Advocate.
Craving simplicity, finding it nowhere.
Internetrovert 🏳️🌈 He/him.
Craving simplicity, finding it nowhere.
Internetrovert 🏳️🌈 He/him.
You know your JS13k submission is going well when you have to resort to `btoa` and other seemingly stupid hacks to get below the file size limit.
September 9, 2025 at 9:45 AM
You know your JS13k submission is going well when you have to resort to `btoa` and other seemingly stupid hacks to get below the file size limit.
Nix friends: How terrible is this idea?
I added `builtins.runWasm` to nix, allowing you to call out to Wasm. The Wasm is reset every time, so the functions remain pure. This gives you a (performant?) escape hatch for things that Nix is missing. E.g parsing YAML (here: via Rust)
I added `builtins.runWasm` to nix, allowing you to call out to Wasm. The Wasm is reset every time, so the functions remain pure. This gives you a (performant?) escape hatch for things that Nix is missing. E.g parsing YAML (here: via Rust)
September 4, 2025 at 2:44 PM
Nix friends: How terrible is this idea?
I added `builtins.runWasm` to nix, allowing you to call out to Wasm. The Wasm is reset every time, so the functions remain pure. This gives you a (performant?) escape hatch for things that Nix is missing. E.g parsing YAML (here: via Rust)
I added `builtins.runWasm` to nix, allowing you to call out to Wasm. The Wasm is reset every time, so the functions remain pure. This gives you a (performant?) escape hatch for things that Nix is missing. E.g parsing YAML (here: via Rust)
Convince me I am wrong: This should not be a type error, right?
- I asserted it’s an object
- I am using `?.` for property access
www.typescriptlang.org/play/#code/G...
- I asserted it’s an object
- I am using `?.` for property access
www.typescriptlang.org/play/#code/G...
July 10, 2025 at 1:40 PM
Convince me I am wrong: This should not be a type error, right?
- I asserted it’s an object
- I am using `?.` for property access
www.typescriptlang.org/play/#code/G...
- I asserted it’s an object
- I am using `?.` for property access
www.typescriptlang.org/play/#code/G...
Unexpected dangers of vibe coding:
Somehow git ended up tracking its own .git folder and now I can't commit anymore :3
Somehow git ended up tracking its own .git folder and now I can't commit anymore :3
March 28, 2025 at 11:01 AM
Unexpected dangers of vibe coding:
Somehow git ended up tracking its own .git folder and now I can't commit anymore :3
Somehow git ended up tracking its own .git folder and now I can't commit anymore :3
Still discovering new shell tricks.
TIL: Substitutions.
`cmd <(cat file)` invokes `cmd` with the first parameter being a named pipe (e.g. `/dev/fd/22`) which contains the contents of `file`.
Example use-case: You wanna diff two files, but they are binary so need disassembling
TIL: Substitutions.
`cmd <(cat file)` invokes `cmd` with the first parameter being a named pipe (e.g. `/dev/fd/22`) which contains the contents of `file`.
Example use-case: You wanna diff two files, but they are binary so need disassembling
September 7, 2024 at 6:10 PM
Still discovering new shell tricks.
TIL: Substitutions.
`cmd <(cat file)` invokes `cmd` with the first parameter being a named pipe (e.g. `/dev/fd/22`) which contains the contents of `file`.
Example use-case: You wanna diff two files, but they are binary so need disassembling
TIL: Substitutions.
`cmd <(cat file)` invokes `cmd` with the first parameter being a named pipe (e.g. `/dev/fd/22`) which contains the contents of `file`.
Example use-case: You wanna diff two files, but they are binary so need disassembling
I find it remarkable that xkcd just casually invented the term "nerd sniping" in a comic, and it is now a completely normal word to use ...
xkcd.com/356/
xkcd.com/356/
August 8, 2024 at 1:37 PM
I find it remarkable that xkcd just casually invented the term "nerd sniping" in a comic, and it is now a completely normal word to use ...
xkcd.com/356/
xkcd.com/356/
Scheduled a pickup with DHL, they never arrived and I can’t schedule a new pickup time.
Went to website and clicked on “Help & Support”. It shows this in response.
10/10 would Lorem Ipsum again.
Went to website and clicked on “Help & Support”. It shows this in response.
10/10 would Lorem Ipsum again.
July 4, 2024 at 8:58 AM
Scheduled a pickup with DHL, they never arrived and I can’t schedule a new pickup time.
Went to website and clicked on “Help & Support”. It shows this in response.
10/10 would Lorem Ipsum again.
Went to website and clicked on “Help & Support”. It shows this in response.
10/10 would Lorem Ipsum again.
(⚠️ Definitely one of the dumber things I have written)
This ES6 Proxy lets you instantiate any WebAssembly module without having to care about every import it requires. It generates an empty function for the ones you don’t provide.
gist.github.com/surma/da12f7...
This ES6 Proxy lets you instantiate any WebAssembly module without having to care about every import it requires. It generates an empty function for the ones you don’t provide.
gist.github.com/surma/da12f7...
May 16, 2024 at 12:34 PM
(⚠️ Definitely one of the dumber things I have written)
This ES6 Proxy lets you instantiate any WebAssembly module without having to care about every import it requires. It generates an empty function for the ones you don’t provide.
gist.github.com/surma/da12f7...
This ES6 Proxy lets you instantiate any WebAssembly module without having to care about every import it requires. It generates an empty function for the ones you don’t provide.
gist.github.com/surma/da12f7...
I added experimental support for JavaScript sourcemaps (both inline and separate) to Wasmphobia.
I liked the idea of making it a one-stop-shop for all your bundle analysis needs 😅
wasmphobia.surma.technology
I liked the idea of making it a one-stop-shop for all your bundle analysis needs 😅
wasmphobia.surma.technology
May 13, 2024 at 10:37 AM
I added experimental support for JavaScript sourcemaps (both inline and separate) to Wasmphobia.
I liked the idea of making it a one-stop-shop for all your bundle analysis needs 😅
wasmphobia.surma.technology
I liked the idea of making it a one-stop-shop for all your bundle analysis needs 😅
wasmphobia.surma.technology
I really wanted to know which libraries are bloating my WebAssembly binaries, so I wrote a visualizer.
Throw in a .wasm file with DWARF debug symbols, and wasmphobia will generate a flame graph for you, breaking down the module by source file.
wasmphobia.surma.technology
Throw in a .wasm file with DWARF debug symbols, and wasmphobia will generate a flame graph for you, breaking down the module by source file.
wasmphobia.surma.technology
May 9, 2024 at 2:44 PM
I really wanted to know which libraries are bloating my WebAssembly binaries, so I wrote a visualizer.
Throw in a .wasm file with DWARF debug symbols, and wasmphobia will generate a flame graph for you, breaking down the module by source file.
wasmphobia.surma.technology
Throw in a .wasm file with DWARF debug symbols, and wasmphobia will generate a flame graph for you, breaking down the module by source file.
wasmphobia.surma.technology
Trying to get started with Kubernetes. Slightly annoyed by the cyclic “you should know about X first” in the docs 🙄
April 13, 2024 at 11:34 PM
Trying to get started with Kubernetes. Slightly annoyed by the cyclic “you should know about X first” in the docs 🙄
Just found a great show-case of AbortController. I don’t think I could make this code as concise without aEL’s support for AC signals.
Note that I need to:
- access `controller` from within the listener,
- access `this` in `start()`
- remove the listener in `cancel()`
Note that I need to:
- access `controller` from within the listener,
- access `this` in `start()`
- remove the listener in `cancel()`
April 11, 2024 at 9:58 PM
Just found a great show-case of AbortController. I don’t think I could make this code as concise without aEL’s support for AC signals.
Note that I need to:
- access `controller` from within the listener,
- access `this` in `start()`
- remove the listener in `cancel()`
Note that I need to:
- access `controller` from within the listener,
- access `this` in `start()`
- remove the listener in `cancel()`
One of my biggest upsets with getting more into smart home & automation is the hard data that my washing machine's "TurboWash 59" program takes 65 minutes.
April 6, 2024 at 11:18 PM
One of my biggest upsets with getting more into smart home & automation is the hard data that my washing machine's "TurboWash 59" program takes 65 minutes.
First time actually playing with the new-ish Navigation API.
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
A very modern API. A lot more control. As a trade-off, not as trivial to implement correctly.
First tripwire for me: `navigationEvent.intercept()` commits the new URL.
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
A very modern API. A lot more control. As a trade-off, not as trivial to implement correctly.
First tripwire for me: `navigationEvent.intercept()` commits the new URL.
June 11, 2023 at 5:08 PM
First time actually playing with the new-ish Navigation API.
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
A very modern API. A lot more control. As a trade-off, not as trivial to implement correctly.
First tripwire for me: `navigationEvent.intercept()` commits the new URL.
https://developer.mozilla.org/en-US/docs/Web/API/Navigation_API
A very modern API. A lot more control. As a trade-off, not as trivial to implement correctly.
First tripwire for me: `navigationEvent.intercept()` commits the new URL.