Robert Balicki
statisticsftw.bsky.social
Robert Balicki
@statisticsftw.bsky.social
770 followers 460 following 590 posts
Creator of Isograph https://github.com/isographlabs/isograph. Check out my talk at GraphQL conf! https://youtu.be/sf8ac2NtwPY?si=jkljEacLsxStFfjg Pinterest, previously Relay team at Meta
Posts Media Videos Starter Packs
And thank you @jem.graphile.org for suggesting the idea of an Unconf!!!!
Reposted by Robert Balicki
First annual Rust NYC Unconf registrations are open!
rust.nyc/unconf
I can't wait for this!! We've had an extremely strong year with
- more meetups than in any previous year,
- the largest meetup we've ever had, and
- the most members of any Rust meetup in the world!

And what better way to celebrate but to cap it off with an unconf!!!
First annual Rust NYC Unconf registrations are open!
rust.nyc/unconf
Reposted by Robert Balicki
I don't think it's impossible for reuse of fragments to be the wrong choice. But, in practice, in any given situation, it likely is.

- Fragments are a way of expressing parameter types, e.g. `function fooNonGraphQL(data: { user: name })` is somewhat equivalent
This has no runtime data masking, but at least tsc will inform you if you remove a field from UserAvatar and someone else was depending on it.

So it's a step. Still 100x better than what most folks do.
type UserCard_propType = { name: string, ...UserAvatar_propType };
function UserCard(data: UserCard_propType) {
return <><h1>{data.name}</h1><UserAvatar data={data} /></>
}
Addendum: are there other statically analyzable ways to express parameters that might have the same properties, without the cruft of GraphQL? Yeah! You can do that.
- Runtime data masking might be harder to achieve, but you can certainly imagine having many of the benefits of GraphQL as follows:
data masking and colocation (and composability.)

/fin
have data masking and colocation, which IMO is the only reason to use GraphQL to build UIs. Everything else (the shit type system, idiotic restrictions left and right like not being able to have interfaces with no fields, the lack of sealed unions/interfaces, etc. is a price to put up with to get
- But if the UserCard function is not the one that consumes that data, then you get the problem above, potentially overfetching.
- So "fragments are not for reuse" is easily misinterpreted! It's bad marketing! Clearly UserCard_user is reused.
- But the downsides of reuse don't occur as long as you
- The verbosity! Oh no! You're right, `best_friend { name, email, 50_other_fields } worse_enemy { name, email, 50_other_fields }` is annoying. And you should replace those selections with a fragment spread: `UserCard_user`
accepted by your framework/GraphQL compiler of choice. But it's also ugly and hard to reason about. So in cases like that, the thing you may want to do is to spread and use a common fragment.
- But realistically, I don't think anyone is thinking at that level. Instead, they think of DevEx
- And *here's the best reason*, you may not have a clear `FooPage1` is rendered before `FooPage2` relationship. What if in both cases you want to ensure that the other one is spread? Well, you'd have to spread `FooPage1` in `FooPage2`, and `FooPage2` in `FooPage1`. That may or may not be
- In addition to this, you may have local changes, e.g. you fetch a user and then add it to a list of friends. Well, then you may want to have spread the FriendList_user fragment, so that we have enough data to render the FriendList. (Same same as the previous example but different.)
- To guarantee that a future function has the data it needs, but IMO that's handled better as `fragment FooPage1 on User { ...FooPage2 }`. `FooPage2` is not called immediately, but we guarantee that we can execute FooPage2 later without a network request. That's a good reason to overfetch!
across multiple functions, if not DevEx? You generally wouldn't!
- Doing so opens up a risk: that you receive more data than you actually use, which (of course) is bad for perf, since that data came from the network.
- So, why might you *want* to opt into receiving more data than you use?
to `fooGraphQL(ref) {const data = useFragment(graphql` fragment Foo on User { name }`, ref)`
- These are input types that are explicitly, easily statically analyzable! c.f. `fooNonGraphQL(data: SomeType)`, which is not easily statically analyzable
- So, why would you reuse a parameter type
I don't think it's impossible for reuse of fragments to be the wrong choice. But, in practice, in any given situation, it likely is.

- Fragments are a way of expressing parameter types, e.g. `function fooNonGraphQL(data: { user: name })` is somewhat equivalent
Associating these statically is great:
- if you're deferring some data, it's probably a best practice to defer the JS! That's two separate steps other frameworks
- Entrypoints and 3D work, without any server support, out of the box, using no fancy machinery

And so much more!
This is a great talk! The key things to note about fragments are that a single function should read a given fragment (i.e. they're not for reuse). isograph.dev is an entire framework built upon taking that to its logical conclusion!
You’re using GraphQL fragments wrong.

They’re not for reuse, they’re for co-location.

Here’s what Meta learned refining this idea 👇🏼
youtube.com/watch?v=gMCh...
How To Use Fragments (They're Not for Re-use!) - Janette Cheng, Meta
YouTube video by GraphQL Foundation Talks
youtube.com
Reposted by Robert Balicki
Vite and Vitest imply the existence of Viter
Reposted by Robert Balicki
Check out this one pager: isograph.dev/docs/how-iso...

TLDR, imagine:
- Relay, but without fragment spreads or other boilerplate, i.e. as if everything was a resolver, and
- if everything is a resolver, you can do a whole bunch of awesome things: defer without server support...
Isograph one-pager | Isograph
A whirlwind tour of Isograph.
isograph.dev
entrypoints without server support.
- Currently, it targets GraphQL + React + JS, but all of those are implementation details (e.g. the user never writes GraphQL)

Lots of other advantages! Check out the quickstart, too: isograph.dev/docs/quickst...
Quickstart guide | Isograph
In this quickstart guide, we will create a new NextJS project and add Isograph to it. Then we'll use the free and publicly available Star Wars GraphQL API.
isograph.dev
Check out this one pager: isograph.dev/docs/how-iso...

TLDR, imagine:
- Relay, but without fragment spreads or other boilerplate, i.e. as if everything was a resolver, and
- if everything is a resolver, you can do a whole bunch of awesome things: defer without server support...
Isograph one-pager | Isograph
A whirlwind tour of Isograph.
isograph.dev
Reposted by Robert Balicki
New blog post: Cancelling async #rustlang!

This is a written version of my talk at #RustConf 2025, where I talk about the joys and sorrows of future cancellations in Rust, with lessons from our work at @oxide.computer. Includes a video of the talk as well. Check it out!
Cancelling async Rust ꞏ sunshowers
Correctness in the face of cancellations: a written version of my talk at RustConf 2025.
sunshowers.io