Surma 's Avatar

Surma

@surma.dev.bsky.social

DX at Shopify. Web Platform Advocate. Craving simplicity, finding it nowhere. Internetrovert ๐Ÿณ๏ธโ€๐ŸŒˆ He/him.

2,975 Followers  |  70 Following  |  44 Posts  |  Joined: 19.05.2023  |  2.0497

Latest posts by surma.dev on Bluesky

Me, sitting behind a cuddly toy of a fox. Ok it's obviously Firefox.

Me, sitting behind a cuddly toy of a fox. Ok it's obviously Firefox.

Starting my new role on Monday. Could be anywhere.

31.07.2025 12:57 โ€” ๐Ÿ‘ 363    ๐Ÿ” 14    ๐Ÿ’ฌ 42    ๐Ÿ“Œ 4
let arr = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]);
console.log(arr.toBase64());
// 'SGVsbG8gV29ybGQ='
console.log(arr.toHex());
// '48656c6c6f20576f726c64'
let string = 'SGVsbG8gV29ybGQ=';
console.log(Uint8Array.fromBase64(string));
// Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100])

string = '48656c6c6f20576f726c64';
console.log(Uint8Array.fromHex(string));
// Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100])

let arr = new Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]); console.log(arr.toBase64()); // 'SGVsbG8gV29ybGQ=' console.log(arr.toHex()); // '48656c6c6f20576f726c64' let string = 'SGVsbG8gV29ybGQ='; console.log(Uint8Array.fromBase64(string)); // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]) string = '48656c6c6f20576f726c64'; console.log(Uint8Array.fromHex(string)); // Uint8Array([72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100])

ECMAScript excitement ๐Ÿ˜‰

Congrats to @bakkot.com on advancing UInt8Array โ†”๏ธ Base64/Hex to Stage 4 at TC39 this week ๐ŸŽ‰

UInt8Array.prototype.
toBase64
toHex

UInt8Array.
fromBase64
fromHex

It lets you convert directly between binary data and Base64/Hex strings ๐Ÿ‘

30.07.2025 06:56 โ€” ๐Ÿ‘ 31    ๐Ÿ” 6    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0

Super happy with hyperoptic

24.07.2025 21:26 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0

Oh that's interesting. I wonder if this is from the merge of ChromeOS and Android.

Let me see if I can install nix :3

18.07.2025 17:25 โ€” ๐Ÿ‘ 3    ๐Ÿ” 0    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 0
Links? Links! - Infrequently Noted Alex Russell on browsers, standards, and the process of progress.

I spent hours and hours trawling through the sites of some of the world's best web developers, and despite the horrors I regularly experience in my daily work in Big JavaScript Territory, what I saw left me hopeful:

infrequently.org/2025/07/links/

16.07.2025 23:17 โ€” ๐Ÿ‘ 84    ๐Ÿ” 19    ๐Ÿ’ฌ 6    ๐Ÿ“Œ 4

No, I'd want `x.a` to still be an error, which would not be the case with `any`. With `?.` I feel like I'm opting in to props that TS is not aware of

11.07.2025 14:29 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Hm... Haven't thought about this nuance too much, but I suppose whenever it is allowed in JS (and behaves by returning undefined) it should be allowed in TS.

10.07.2025 21:36 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

You are prescribing intent that isnโ€™t here. I know what I am checking.

The question boils down to: Should `o?.x` be a *type error* if `x` does not exist on the type of `o`. I claim โ€œnoโ€.

Checking/using properties that TS is unaware is often required, especially at an API boundary.

10.07.2025 20:34 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

I'm proposing that `o?.x` is not a *type error* if `x` does not exist on o's type.

10.07.2025 18:08 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Yes. I know how typescript currently works. I'm claiming that TS should change it's behavior here (hence why I said "this should not be a type error, right?"). I thought you were saying that what I was doing here is wrong at the type theory level, which I don't think is the case.

10.07.2025 17:20 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Why not?

10.07.2025 16:24 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Right, I know how to work around it. But I am asking: Shouldnโ€™t this be accepted by the type checker (because `null?.a` is perfectly valid)

10.07.2025 16:07 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0

Yes, but I specifically donโ€™t want to use any because then you get to access any property without it being an error.

10.07.2025 14:08 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0
Post image

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...

10.07.2025 13:40 โ€” ๐Ÿ‘ 5    ๐Ÿ” 0    ๐Ÿ’ฌ 11    ๐Ÿ“Œ 0

๐Ÿคฆ Iโ€™m a professional engineer, fyi.

Should be fixed now ๐Ÿ™„

18.06.2025 09:03 โ€” ๐Ÿ‘ 6    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
Animating zooming using CSS: transform order is importantโ€ฆ sometimes How to get the right transform animation.

CSS uses a complex algorithm to decide how to animate transforms. If you get it wrong, as many folks do, you end up with an unnatural animation.

Here's how it works, and how to avoid the pitfalls.

jakearchibald.com/2025/animati...

17.06.2025 11:20 โ€” ๐Ÿ‘ 229    ๐Ÿ” 50    ๐Ÿ’ฌ 13    ๐Ÿ“Œ 2

Should be fixed <3

17.06.2025 19:52 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0

Oh how weird! Chrome doesnโ€™t render it like that at all.

Thanks mate, will fix that later today!

17.06.2025 16:55 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
LangGraph for complex workflows โ€” surma.dev I may be late to the party, but LangGraph lets you build complex workflow architectures and codify them as powerful automations. Also LLMs, if you want. But you donโ€™t have to!

๐Ÿ“ First blog in a long time!

I always like โ€œflow-basedโ€ programming, and itโ€™s a very powerful paradigm. LangGraph lets you codify complex workflows as graphs, and also integrates really well with LangChain, if your workflow is LLM-driven.

surma.dev/things/langg...

17.06.2025 16:19 โ€” ๐Ÿ‘ 53    ๐Ÿ” 6    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Post image

Unexpected dangers of vibe coding:
Somehow git ended up tracking its own .git folder and now I can't commit anymore :3

28.03.2025 11:01 โ€” ๐Ÿ‘ 18    ๐Ÿ” 1    ๐Ÿ’ฌ 3    ๐Ÿ“Œ 1

This is IRC. Let's do IRC. I miss IRC

17.03.2025 10:48 โ€” ๐Ÿ‘ 6    ๐Ÿ” 0    ๐Ÿ’ฌ 3    ๐Ÿ“Œ 0

I did consider this, but it presumes that every type parameter is only used as a function parameter type. It will get very cumbersome for more complex type signatures (like nested generic). This work has already been done in `mapper`, just not exposed :S

21.01.2025 13:48 โ€” ๐Ÿ‘ 0    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
typeargs.ts GitHub Gist: instantly share code, notes, and snippets.

Folks who know their way around the TypeScript type checker, I need help:

gist.github.com/surma/be14ca...

How do I figure out what types the type parameters have been bound to given a `CallExpression`? I know the answer is in `resolvedSignature.mapper`, but thatโ€™s not a public API.

20.01.2025 11:55 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
WebAssembly System Interface (WASI) | Node.js v23.6.0 Documentation

Wait, am I dumb? What does NodeJS' WASI implementation only accept file descriptor numbers for stdio? Why don't they allow a Readables/Writables? How are you supposed to capture the output of a WASI module?

nodejs.org/api/wasi.htm...

18.01.2025 13:46 โ€” ๐Ÿ‘ 1    ๐Ÿ” 0    ๐Ÿ’ฌ 2    ๐Ÿ“Œ 0
Preview
New View Transition Stuff - Off The Main Thread Recently added stuff, and ideas for the future

๐Ÿ”Š It's new OTMT time! Me and @surma.dev chat through some newer View Transitions features that have recently landed in browsers, and some things that might land this year.

โฌ‡๏ธ Pop this in your ears โฌ‡๏ธ
offthemainthread.tech/episode/new-...

15.01.2025 11:39 โ€” ๐Ÿ‘ 104    ๐Ÿ” 15    ๐Ÿ’ฌ 8    ๐Ÿ“Œ 3
Preview
The new stylable <select> element - Off The Main Thread And 10 other features we got along the way

Ooh just caught this #OTMT episode on customizable select ๐Ÿ˜Ž Always love to hear @surma.dev and @jakearchibald.com chat about the web and especially the features Iโ€™ve been working on for the past few years ๐Ÿฅฐ

offthemainthread.tech/episode/styl...

07.01.2025 00:07 โ€” ๐Ÿ‘ 66    ๐Ÿ” 6    ๐Ÿ’ฌ 0    ๐Ÿ“Œ 4
Preview
TC39 Roundup Drama Edition Part II: JS0 and JSSugar - Off The Main Thread Splitting JavaScript into two languages

I apologize for splitting the last OTMT episode into two parts. It was sincerely unplanned.

๐ŸŽง Part II of the TC39 Drama ๐ŸŒถ๏ธ Roundup is now out!

In this one, I talk to @jakearchibald.com about JS0, which proposes to split JavaScript into two specifications.

offthemainthread.tech/episode/tc39...

16.12.2024 13:25 โ€” ๐Ÿ‘ 36    ๐Ÿ” 3    ๐Ÿ’ฌ 4    ๐Ÿ“Œ 1
Preview
TC39 Roundup Drama Edition Part II: JS0 and JSSugar - Off The Main Thread Splitting JavaScript into two languages

I apologize for splitting the last OTMT episode into two parts. It was sincerely unplanned.

๐ŸŽง Part II of the TC39 Drama ๐ŸŒถ๏ธ Roundup is now out!

In this one, I talk to @jakearchibald.com about JS0, which proposes to split JavaScript into two specifications.

offthemainthread.tech/episode/tc39...

16.12.2024 13:25 โ€” ๐Ÿ‘ 36    ๐Ÿ” 3    ๐Ÿ’ฌ 4    ๐Ÿ“Œ 1

I should have known and clarified this, but I got flustered during recording because of the research break that was necessary

03.12.2024 18:32 โ€” ๐Ÿ‘ 2    ๐Ÿ” 0    ๐Ÿ’ฌ 1    ๐Ÿ“Œ 0
Preview
TC39 Roundup Drama Edition Part I: Shared Structs - Off The Main Thread Sharing JS objects between worker and main thread

๐ŸŽง A brand-new OTMT episode should be in your podcast players by now:
The TC39 Roundup ๐ŸŒถ๏ธ Drama Edition โ€” Part I

I talk to @jakearchibald.com about the TC39 Structs proposal and how it is a big step towards shared-data multithreading in JS.

offthemainthread.tech/episode/tc39...

03.12.2024 14:11 โ€” ๐Ÿ‘ 36    ๐Ÿ” 5    ๐Ÿ’ฌ 3    ๐Ÿ“Œ 1

@surma.dev is following 20 prominent accounts