Sign in

Kevin Gibbons

@bakkot.com
68 followers 33 following 36 posts
PostsRepliesMedia
Kevin Gibbons @bakkot.com · 18/09/2026
I am very confused about the `--vfs-mount` flag. What does it mean to mount a VFS without also returning a handle to it? How could you ever use that? None of the docs or tests cover this afaict.
110
Kevin Gibbons @bakkot.com · 16/09/2026
"node:dots"?
110
Kevin Gibbons @bakkot.com · 06/09/2026
re: multipage spec for ecma262 - if you hit `m` on the spec webpage it switches to multipage; I don't know if that's what you meant but it's not super obvious so figured I'd mention just in case (there's a handful of other shortcuts; hit `?` to see)
100
Kevin Gibbons @bakkot.com · 30/07/2026
It's true that, as with most things (not just standards), the primary bottleneck is people having the time and interest to pursue them, although this is usually less "heroics" and more "getting your employer to commit 20% of your time" - itself unusual as many companies don't think it's worth it.
020
Kevin Gibbons @bakkot.com · 30/07/2026
The main person who was championing them got sick and then changed jobs. There's not enough people working on the committee for someone else to have picked it up yet. No red light except lack of people's time.
170
Kevin Gibbons @bakkot.com · 18/06/2026
Done, thanks (I always forget phones exist).
020
Kevin Gibbons @bakkot.com · 18/06/2026
I've been playing around with an implementation of concurrent versions of AsyncIterator.prototype.{map,filter,flatMap}. Ended up making a visualizer where you can drive the Promises yourself, which I think helps understand how it behaves. Let me know your thoughts. bakkot.github.io/async-iterat...
bakkot.github.io
Concurrent AsyncIterator .filter
130
Kevin Gibbons @bakkot.com · 24/04/2026
I'm working on fixing a longstanding memory leak in Promise.race in V8. Right now the thing in the way is getting a node maintainer to apply one suggestion and land a small open PR which already has four approvals. Anyone able to help? github.com/nodejs/node/...
github.com
src: skip JS callback for settled Promise.race losers by Felipeness · Pull Request #62336 · nodejs/node
Summary Fixes #51452 When Promise.race() settles, V8 fires kPromiseResolveAfterResolved / kPromiseRejectAfterResolved for each "losing" promise. Node's PromiseRejectCallback in src/no...
150
Kevin Gibbons @bakkot.com · 23/03/2026
I think if you examine the actual dependency tree of a nontrivial app, none of these will really stand out, especially if you weight by the amount they contribute to the built size rather than simply count of packages. Splitting large packages into many small ones can help reduce bundle size, even.
000
Kevin Gibbons @bakkot.com · 28/02/2026
It makes sense, but it's an excessive amount of boilerplate which almost no one actually writes. And while it is concurrency, it's not _structured_ concurrency because it doesn't wait for task cleanup to finish in case of errors - so control moves past the block while the tasks are still running.
130
Kevin Gibbons @bakkot.com · 28/02/2026
Thanks, fixed.
010
Kevin Gibbons @bakkot.com · 28/02/2026
Put together a presentation on a possible direction for getting native structured concurrency in JS, taking as a constraint that we already live in a world where cancellation means AbortController. Interested in your thoughts! docs.google.com/presentation...
docs.google.com
Towards structured concurrency
Towards Structured Concurrency
4133
Kevin Gibbons @bakkot.com · 23/02/2026
Yup! You can also do this for IIFEs (which have a similar restriction to avoid ambiguity with FunctionDeclaration) but there's less reason to care in that case.
010
Kevin Gibbons @bakkot.com · 23/02/2026
It's more common when there's more than one property. `({ user, body, message } = getRequest());` is much nicer to read than `const request = getRequest(); user = request.user; body = request.body; message = request.message;`. That said, yes, I also use destructuring for a single property.
100
Kevin Gibbons @bakkot.com · 23/02/2026
Only because no one uses it! If we all started doing this then people would recognize this pattern.
010
Kevin Gibbons @bakkot.com · 23/02/2026
My most idiosyncratic JS opinion is that we should all write `0, { x } = y;` instead of `({ x } = y);` so you don't have to jump to the end of the line to add the parenthesis. If only I could convince tooling to support this... (i.e. get prettier not to add the parentheses back)
490
Kevin Gibbons @bakkot.com · 28/01/2026
With this attitude, TS becomes much more pleasurable. You can write the code you were going to write anyway but with types written down instead of in your head, and most of the time TS will validate it or catch real bugs, and in the remaining cases you just tell it the right answer and move on.
021
Kevin Gibbons @bakkot.com · 28/01/2026
I really like to emphasize to people that TypeScript is going to be wrong about things sometimes, and you need to embrace that this is OK and that you can and should use `// @ts-expect-error` or `as unknown as Foo` in cases where you know better than the typechecker. It's fine!
231
Kevin Gibbons @bakkot.com · 15/01/2026
This is such a quintessential "working on JavaScript [and friends]" bug. Dumb compat hacks for engines no one has touched in a decade? Check. Weird parser inconsistencies? Check. Even a BOM mention!
030
Kevin Gibbons @bakkot.com · 16/12/2025
If we go with "visible in else" it's actually pretty hard to get disposal to happen before the else! Try rewriting this without relying on "dispose before else": if (using resource = getResource(); resource.needsUpdate) { resource.update(); } else { await postMessage('no updates required'); }
010
Kevin Gibbons @bakkot.com · 09/12/2025
Just because that's how you call always `hasOwnProperty` though, it's not something the attacker could actually control. They could have done `Object.hasOwn` if they only cared to work on modern runtimes, and would not benefit from caching in that case.
110
Kevin Gibbons @bakkot.com · 09/12/2025
As a person who says the thing you quoted all the time I am confused about the relevance of this CVE, which does not modify any builtins?
100
Kevin Gibbons @bakkot.com · 19/11/2025
Agreed! I will probably do this as a followup, but have to get regular async helpers first. github.com/tc39/proposa...
github.com
AsyncIterator.race/merge · Issue #15 · tc39/proposal-async-iterator-helpers
Wanted to write this down so I don't forget, though it won't be in the first version of this proposal. We should have a helper for merging or racing multiple AsyncIterators. When next is first call...
030
Kevin Gibbons @bakkot.com · 06/11/2025
Discworld has good values and was this for me at that age. The Tiffany Aching books especially though he might be turned off by 9yo girl protag. Some of Doctorow's stuff is more explicitly inculcating those specific values, and is good for 13yos. Little Brother is probably a decent first one.
020
Kevin Gibbons @bakkot.com · 18/09/2025
Several people blamed the recent npm incidents on JS's minimal standard library. I think that's wrong: the affected packages are mostly either already covered by node or could not reasonably be in a standard library. But! I'm always taking suggestions for new stdlib features.
160
Kevin Gibbons @bakkot.com · 13/09/2025
Not exactly stalled; there's just a lot of work which needs to be done first. Activity currently is at github.com/tc39/proposa.... I believe the plan is for module declarations to proceed after this proposal, with the declaration evaluating to the ModuleSource object introduced in this proposal.
github.com
GitHub - tc39/proposal-esm-phase-imports
Contribute to tc39/proposal-esm-phase-imports development by creating an account on GitHub.
030
Kevin Gibbons @bakkot.com · 31/07/2025
That's because this isn't upsert. Upsert does mutation when the value already exists. This doesn't.
130
Kevin Gibbons @bakkot.com · 11/07/2025
Pedantry: you made a quiz about _V8_'s Date parser. Almost none of this is required by spec (although it is allowed), and several of these behave differently in other browsers. Which is even worse!
0100
Kevin Gibbons @bakkot.com · 22/05/2025
A sync iterator yielding a rejected promise is not an error in the iterator, whereas an async iterators doing so is. So when lifting sync to async, we need to handle rejected promises from the iterator as if the _consumer_ had an error (by calling `.return`).
010
Kevin Gibbons @bakkot.com · 22/05/2025
Thanks! Further pedantry: "Note that in for of with sync iterators, .return() is always called after .next() throws" - not so. The bug arises because consumers aren't supposed to call .return if the iterator throws, only if the consumer does.
100
Kevin Gibbons @bakkot.com · 22/05/2025
So, a break/return/throw inside the loop causes `.return` to be called, but the iterator being exhausted, or throwing, does not call `.return` to be called.
100
Kevin Gibbons @bakkot.com · 22/05/2025
Good post! Nitpick: you say `.return` is called "when the iteration stops (due to a break, due to reaching the end of the iterator, or due to the iterator having thrown)". The latter 2 are wrong. It is called only on _early_ exits from the loop which are not caused by the iterator throwing.
100
Kevin Gibbons @bakkot.com · 05/05/2025
Some of that is because the lack of syntax means we don't clean up things we probably should. For example, with a [hypothetical] disposable AbortController, it would be trivial to clean up outstanding fetch requests when other requests fail. Usually JS devs just don't bother.
using controller = new AbortController.AutoAbort();
let pages = await Promise.all(urls.map(url => fetch(url, { signal: controller.signal }));
// automatically cancels outstanding requests if any request fails
030
Kevin Gibbons @bakkot.com · 21/03/2025
we have almost finished working through your list chunking is coming in proposal-iterator-chunking ranges are making less progress rest is done x.com/qntm/status/...
x.com
000
Kevin Gibbons @bakkot.com · 31/12/2024
Any pointers to which? I've previously been skeptical of adding CBOR because I thought it didn't have wide adoption yet but it's already backing web specs that would be relevant data.
100
Kevin Gibbons @bakkot.com · 26/11/2024
Parallelism and concurrency! respectively: github.com/tc39/proposa... github.com/tc39/proposa... less exciting but still exciting (but I'm biased): native base64 github.com/tc39/proposa...
140