Training Example: overreacted (Dan Abramov) – Review the Data, Give Your Score & Compare to the Real AI Evaluation

Industry Context — Common BS Fingerprints in Blogs, Influencers & Personal Brands
Generic Claims: helping you live your best life, inspiring millions, building an authentic community, trusted voice in the space…
Red Flags: follower count claims without linked profiles, no sponsorship or affiliate disclosure, expertise claims without credentials or track record, media kit with vanity metrics only…
Semantic Drift Patterns: claims expertise in a niche but content spans unrelated topics, homepage positions as authority but content is surface-level, claims independence but most content is sponsored, personal brand claims authenticity but every post is commercially driven…
Proof Expectations: verifiable follower counts on linked social profiles, named brand partnerships with specific campaigns, published content with dates and engagement metrics, named media appearances with links…

overreacted (Dan Abramov)

(https://overreacted.io) 📸 Data Snapshot: May 25, 2026

Analyze the raw signals below. How would a machine score this business’s credibility?

Here are the exact signals captured from up to six pages of the site — the same raw inputs the evaluation engine analyzed. They are grouped by signal type so you can weigh each the way the machine does.

🏗️ Semantic Structure — heading hierarchy & page identity (Info Density · Commodity Fingerprint)
HOMEPAGE overreacted — A blog by Dan Abramov (https://overreacted.io)
Title

overreacted — A blog by Dan Abramov

Meta

A blog by Dan Abramov

H2 A Social Filesystem
H2 Introducing RSC Explorer
H2 Hire Me in Japan
H2 How to Fix Any Bug
H2 Where It's at://
H2 Open Social
H2 A Lean Syntax Primer
H2 Beyond Booleans
H2 The Math Is Haunted
H2 Suppressions of Suppressions
H2 I'm Doing a Little Consulting
H2 How Imports Work in RSC
H2 RSC for LISP Developers
H2 Progressive JSON
H2 Why Does RSC Integrate with a Bundler?
H2 One Roundtrip Per Navigation
H2 Static as a Server
H2 RSC for Astro Developers
H2 Functional HTML
H2 What Does "use client" Do?
H2 Impossible Components
H2 JSX Over The Wire
H2 React for Two Computers
H2 The Two Reacts
H2 A Chain Reaction
H2 npm audit: Broken by Design
H2 Before You memo()
H2 The WET Codebase
H2 Goodbye, Clean Code
H2 My Decade in Review
H2 What Are the React Team Principles?
H2 On let vs const
H2 What Is JavaScript Made Of?
H2 How Does the Development Mode Work?
H2 Algebraic Effects for the Rest of Us
H2 Preparing for a Tech Talk, Part 3: Content
H2 Name It, and They Will Come
H2 Writing Resilient Components
H2 A Complete Guide to useEffect
H2 How Are Function Components Different from Classes?
H2 Coping with Feedback
H2 Fix Like No One’s Watching
H2 Making setInterval Declarative with React Hooks
H2 React as a UI Runtime
H2 Why Isn’t X a Hook?
H2 The “Bug-O” Notation
H2 Preparing for a Tech Talk, Part 2: What, Why, and How
H2 The Elements of UI Engineering
H2 Things I Don’t Know as of 2018
H2 Preparing for a Tech Talk, Part 1: Motivation
H2 Why Do React Hooks Rely on Call Order?
H2 Optimized for Change
H2 How Does setState Know What to Do?
H2 My Wishlist for Hot Reloading
H2 Why Do React Elements Have a $$typeof Property?
H2 How Does React Tell a Class from a Function?
H2 Why Do We Write super(props)?
HEADING_BODY A Social Filesystem — overreacted (https://overreacted.io/a-social-filesystem/)
Title

A Social Filesystem — overreacted

Meta

Formats over apps.

H1 A Social Filesystem
H2 #Why Files Are Awesome
H2 #The Everything Folder
H2 #A Social Filesystem
H2 #Up in the Atmosphere
H3 #A Record
H3 #Record Keys
H3 #Lexicons
H3 #Collections
H3 #There Is No Lexicon Police
H3 #Links
H3 #Identity
H3 #at:// URI
H3 #Hyperlinks for JSON
H3 #A Repository
H4 #Attempt 1: Host as Identity
H4 #Attempt 2: Handle as Identity
H4 #Attempt 3: Domain as Identity
H4 #Attempt 4: Hash as Identity
H4 #Attempt 5: DID as Identity
HEADING_BODY Introducing RSC Explorer — overreacted (https://overreacted.io/introducing-rsc-explorer/)
Title

Introducing RSC Explorer — overreacted

Meta

My new hobby project.

H1 Introducing RSC Explorer
H2 #Async Component
H2 #Counter
H2 #Form Action
H2 #Router Refresh
H2 #What Else?
HEADING_BODY Hire Me in Japan — overreacted (https://overreacted.io/hire-me-in-japan/)
Title

Hire Me in Japan — overreacted

Meta

I'm looking for a new job.

H1 Hire Me in Japan
H3 #Past Work
H3 #Looking Forward
H3 #Why Japan
H4 #2025: Consulting
H4 #2023–2025: The Bluesky app
H4 #2015–2023: React at Meta/Facebook
H4 #Before 2015
📝 The Narrative — clean text per page (Info Density · Semantic Coherence)
HOMEPAGE (https://overreacted.io) overreacted — A blog by Dan Abramov
[H2] A Social Filesystem
January 18, 2026Formats over apps.
[H2] Introducing RSC Explorer
December 19, 2025My new hobby project.
[H2] Hire Me in Japan
November 11, 2025I'm looking for a new job.
[H2] How to Fix Any Bug
October 21, 2025The joys of vibecoding.
[H2] Where It's at://
October 2, 2025From handles to hosting.
[H2] Open Social
September 26, 2025The protocol is the API.
[H2] A Lean Syntax Primer
September 2, 2025Programming with proofs.
[H2] Beyond Booleans
August 16, 2025What is the type of 2 + 2 = 4?
[H2] The Math Is Haunted
July 30, 2025A taste of Lean.
[H2] Suppressions of Suppressions
June 11, 2025I heard you like linting.
[H2] I'm Doing a Little Consulting
June 11, 2025Personal update post.
[H2] How Imports Work in RSC
June 5, 2025A layered module system.
[H2] RSC for LISP Developers
June 1, 2025Quoting for modules.
[H2] Progressive JSON
May 31, 2025Why streaming isn't enough.
[H2] Why Does RSC Integrate with a Bundler?
May 30, 2025One does not simply serialize a module.
[H2] One Roundtrip Per Navigation
May 29, 2025What do HTML, GraphQL, and RSC have in common?
[H2] Static as a Server
May 8, 2025You wouldn't download a site.
[H2] RSC for Astro Developers
May 6, 2025Islands, but make it fractal.
[H2] Functional HTML
May 2, 2025Tags on both sides.
[H2] What Does "use client" Do?
April 25, 2025Two worlds, two doors.
[H2] Impossible Components
April 22, 2025Composing across the stack.
[H2] JSX Over The Wire
April 16, 2025Turning your API inside-out.
[H2] React for Two Computers
April 9, 2025Two things, one origin.
[H2] The Two Reacts
January 4, 2024UI = f(data)(state)
[H2] A Chain Reaction
December 11, 2023The limits of my language mean the limits of my world.
[H2] npm audit: Broken by Design
July 7, 2021Found 99 vulnerabilities (84 moderately irrelevant, 15 highly irrelevant)
[H2] Before You memo()
February 23, 2021Rendering optimizations that come naturally.
[H2] The WET Codebase
July 13, 2020Come waste your time with me.
[H2] Goodbye, Clean Code
January 11, 2020Let clean code guide you. Then let it go.
[H2] My Decade in Review
January 1, 2020A personal reflection.
[H2] What Are the React Team Principles?
December 25, 2019UI Before API.
[H2] On let vs const
December 22, 2019So which one should I use?
[H2] What Is JavaScript Made Of?
December 20, 2019Getting a closure on JavaScript.
[H2] How Does the Development Mode Work?
August 4, 2019Dead code elimination by convention.
[H2] Algebraic Effects for the Rest of Us
July 21, 2019They’re not burritos.
[H2] Preparing for a Tech Talk, Part 3: Content
July 10, 2019Turning an idea into a talk.
[H2] Name It, and They Will Come
March 25, 2019A change starts with a story.
[H2] Writing Resilient Components
March 16, 2019Four principles to set you on the right path.
[H2] A Complete Guide to useEffect
March 9, 2019Effects are a part of your data flow.
[H2] How Are Function Components Different from Classes?
March 3, 2019They’re a whole different Pokémon.
[H2] Coping with Feedback
March 2, 2019Sometimes I can’t fall asleep.
[H2] Fix Like No One’s Watching
February 15, 2019The other kind of technical debt.
[H2] Making setInterval Declarative with React Hooks
February 4, 2019How I learned to stop worrying and love refs.
[H2] React as a UI Runtime
February 2, 2019An in-depth description of the React programming model.
[H2] Why Isn’t X a Hook?
January 26, 2019Just because we can, doesn’t mean we should.
[H2] The “Bug-O” Notation
January 25, 2019What is the ?(n) of your API?
[H2] Preparing for a Tech Talk, Part 2: What, Why, and How
January 7, 2019We need to go deeper.
[H2] The Elements of UI Engineering
December 30, 2018What makes UI engineering difficult?
[H2] Things I Don’t Know as of 2018
December 28, 2018We can admit our knowledge gaps without devaluing our expertise.
[H2] Preparing for a Tech Talk, Part 1: Motivation
December 26, 2018Here’s my recipe for a good talk idea.
[H2] Why Do React Hooks Rely on Call Order?
December 13, 2018Lessons learned from mixins, render props, HOCs, and classes.
[H2] Optimized for Change
December 12, 2018What makes a great API?
[H2] How Does setState Know What to Do?
December 9, 2018Dependency injection is nice if you don’t have to think about it.
[H2] My Wishlist for Hot Reloading
December 8, 2018I don't want a lot for Christmas. There is just one thing I need.
[H2] Why Do React Elements Have a $$typeof Property?
December 3, 2018It has something to do with security.
[H2] How Does React Tell a Class from a Function?
December 2, 2018We talk about classes, new, instanceof, prototype chains, and API design.
[H2] Why Do We Write super(props)?
November 30, 2018There’s a twist at the end.
4648 chars
SUB-PAGE (https://overreacted.io/a-social-filesystem/) A Social Filesystem — overreacted
[H1] A Social Filesystem
January 18, 2026Pay what you likeRemember files?
You write a document, hit save, and the file is on your computer. It’s yours. You can inspect it, you can send it to a friend, and you can open it with other apps.
Files come from the paradigm of personal computing.
This post, however, isn’t about personal computing. What I want to talk about is social computing—apps like Instagram, Reddit, Tumblr, GitHub, and TikTok.
What do files have to do with social computing?
Historically, not a lot—until recently.
But first, a shoutout to files.
[H2] #Why Files Are Awesome
Files, as originally invented, were not meant to live inside the apps.
Since files represent your creations, they should live somewhere that you control. Apps create and read your files on your behalf, but files don’t belong to the apps.
Files belong to you—the person using those apps.
Apps (and their developers) may not own your files, but they do need to be able to read and write them. To do that reliably, apps need your files to be structured. This is why app developers, as part of creating apps, may invent and evolve file formats.
A file format is like a language. An app might “speak” several formats. A single format can be understood by many apps. Apps and formats are many-to-many. File formats let different apps work together without knowing about each other.
Consider this .svg:
SVG is an open specification. This means that different developers agree on how to read and write SVG. I created this SVG file in Excalidraw, but I could have used Adobe Illustrator or Inkscape instead. Your browser already knew how to display this SVG. It didn’t need to hit any Excalidraw APIs or to ask permissions from Excalidraw to display this SVG. It doesn’t matter which app has created this SVG.
The file format is the API.
Of course, not all file formats are open or documented.
Some file formats are application-specific or even proprietary like .doc. And yet, although .doc was undocumented, it didn’t stop motivated developers from reverse-engineering it and creating more software that reads and writes .doc:
Another win for the files paradigm.
The files paradigm captures a real-world intuition about tools: what we make with a tool does not belong to the tool. A manuscript doesn’t stay inside the typewriter, a photo doesn’t stay inside the camera, and a song doesn’t stay in the microphone.
Our memories, our thoughts, our designs should outlive the software we used to create them. An app-agnostic storage (the filesystem) enforces this separation.
A file has many lives.
You may create a file in one app, but someone else can read it using another app. You may switch the apps you use, or use them together. You may convert a file from one format to another. As long as two apps correctly “speak” the same file format, they can work in tandem even if their developers hate each others’ guts.
And if the app sucks?
Someone could always create “the next app” for the files you already have:
Apps may come and go, but files stay—at least, as long as our apps think in files.
[H2] #The Everything Folder
When you think of social apps—Instagram, Reddit, Tumblr, GitHub, TikTok—you probably don’t think about files. Files are for personal computing only, right?
A Tumblr post isn’t a file.
An Instagram follow isn’t a file.
A Hacker News upvote isn’t a file.
But what if they behaved as files—at least, in all the important ways? Suppose you had a folder that contained all of the things ever POSTed by your online persona:
It would include everything you’ve created across different social apps—your posts, likes, scrobbles, recipes, etc. Maybe we can call it your “everything folder”.
Of course, closed apps like Instagram aren’t built this way. But imagine they were. In that world, a “Tumblr post” or an “Instagram follow” are social file formats:
You posting on Tumblr would create a “Tumblr post” file in your folder.
You following on Instagram would put an “Instagram follow” file into your folder.
You upvoting on Hacker News would add an “HN upvote” file to your folder.
Note this folder is not some kind of an archive. It’s where your data actually lives:
Files are the source of truth—the apps would reflect whatever’s in your folder.
Any writes to your folder would be synced to the interested apps. For example, deleting an “Instagram follow” file would work just as well as unfollowing through the app. Crossposting to three Tumblr communities could be done by creating three “Tumblr post” files. Under the hood, each app manages files in your folder.
In this paradigm, apps are reactive to files. Every app’s database mostly becomes derived data—an app-specific cached materialized view of everybody’s folders.
[H2] #A Social Filesystem
This might sound very hypothetical, but it’s not. What I’ve described so far is the premise behind the AT protocol. It works in production at scale. Bluesky, Leaflet, Tangled, Semble, and Wisp are some of the new open social apps built this way.
It doesn’t feel different to use those apps. But by lifting user data out of the apps, we force the same separation as we’ve had in personal computing: apps don’t trap what you make with them. Someone can always make a new app for old data:
Like before, app developers evolve their file formats. However, they can’t gatekeep who reads and writes files in those formats. Which apps to use is up to you.
Together, everyone’s folders form something like a distributed social filesystem:
I’ve previously written about the AT protocol in Open Social, looking at its model from a web-centric perspective. But I think that looking at it from the filesystem perspective is just as intriguing, so I invite you to take a tour of how it works.
A personal filesystem starts with a file.
What does a social filesystem start with?
[H3] #A Record
Here is a typical social media post:
How would you represent it as a file?
It’s natural to consider JSON as a format. After all, that’s what you’d return if you were building an API. So let’s fully describe this post as a piece of JSON:
{
author: {
avatar: 'https://example.com/dril.jpg',
displayName: 'wint',
handle: 'dril'
},
text: 'no',
createdAt: '2008-09-15T17:25:00.000Z',
replyCount: 819,
repostCount: 56137,
likeCount: 125381
}
However, if we want to store this post as a file, it doesn’t make sense to embed the author information there. After all, if the author later changes their display name or avatar, we wouldn’t want to go through their every post and change them there.
So let’s assume their avatar and name live somewhere else—perhaps, in another file. We could leave author: 'dril' in the JSON but this is unnecessary too. Since this file lives inside the creator’s folder—it’s their post, after all—we can always figure out the author based on whose folder we’re currently looking at.
Let’s remove the author field completely:
{
text: 'no',
createdAt: '2008-09-15T17:25:00.000Z',
replyCount: 819,
repostCount: 56137,
likeCount: 125381
}
This seems like a good way to describe this post:
But wait, no, this is still wrong.
You see, replyCount, repostCount, and likeCount are not really something that the post’s author has created. These values are derived from the data created by other people—their replies, their reposts, their likes. The app that displays this post will have to keep track of those somehow, but they aren’t this user’s data.
So really, we’re left with just this:
{
text: 'no',
createdAt: '2008-09-15T17:25:00.000Z'
}
That’s our post as a file!
Notice how it took some trimming to identify which parts of the data actually belong in this file. This is something that you have to be intentional about when creating apps with the AT protocol. My mental model for this is to think about the POST request. When the user created this thing, what data did they send? That’s likely close to what we’ll want to store. That’s the stuff the user has just created.
Our social filesystem will be structured more rigidly than a traditional filesystem. For example, it will only consist of JSON files. To make this more explicit, we’ll start introducing our new terminology. We’ll call this kind of file a record.
[H3] #Record Keys
Now we need to give our record a name. There are no natural names for posts. Could we use sequential numbers? Our names need only be unique within a folder:
posts/
├── 1.json
├── 2.json
└── 3.json
One downside is that we’d have to keep track of the latest one so there’s a risk of collisions when creating many files from different devices at the same time.
Instead, let’s use timestamps with some per-clock randomness mixed in:
posts/
├── 1221499500000000-c5.json
├── 1221499500000000-k3.json # clock id helps avoid global collisions
└── 1221499500000001-k3.json # artificial +1 avoids local collisions
This is nicer because these can be generated locally and will almost never collide.
We’ll use these names in URLs so let’s encode them more compactly. We’ll pick our encoding carefully so that sorting alphabetically goes in the chronological order:
posts/
├── 34qye3wows2c5.json
├── 34qye3wows2k3.json
└── 34qye3wows3k3.json
Now ls -r gives us a reverse chronological timeline of posts! That’s neat. Also, since we’re sticking with JSON as our lingua franca, we don’t need file extensions.
posts/
├── 34qye3wows2c5
├── 34qye3wows2k3
└── 34qye3wows3k3
Not all records accumulate over time. For example, you can write many posts, but you only have one copy of profile information—your avatar and display name. For “singleton” records, it makes sense to use a predefined name, like me or self:
posts/
├── 34qye3wows2c5
├── 34qye3wows2k3
└── 34qye3wows3k3
profiles/
└── self
By the way, let’s save this profile record to profiles/self:
{
avatar: 'https://example.com/dril.jpg",
displayName: 'wint'
}
Note how, taken together, posts/34qye3wows2c5 and profiles/self let us reconstruct more of the UI we started with, although some parts are still missing:
Before we fill them in, though, we need to make our system sturdier.
[H3] #Lexicons
This was the shape of our post record:
{
text: 'no',
createdAt: '2008-09-15T17:25:00.000Z'
}
And this was the shape of our profile record:
{
avatar: 'https://example.com/dril.jpg",
displayName: 'wint'
}
Since these are stored as files, it’s important for the format not to drift.
Let’s write some type definitions:
type Post = {
text: string,
createdAt: string
};
type Profile = {
avatar?: string,
displayName?: string
};
TypeScript seems convenient for this but it isn’t sufficient. For example, we can’t express constraints like “the text string should have at most 300 Unicode graphemes”, or “the createdAt string should be formatted as datetime”.
We need a richer way to define social file formats.
We might shop around for existing options (RDF? JSON Schema?) but if nothing quite fits, we might as well design our own schema language explicitly geared towards the needs of our social filesystem. This is what our Post looks like:
{
// ...
"defs": {
"main": {
"type": "record",
"key": "tid",
"record": {
"type": "object",
"required": ["text", "createdAt"],
"properties": {
"text": { "type": "string", "maxGraphemes": 300 },
"createdAt": { "type": "string", "format": "datetime" }
}
}
}
}
}
We’ll call this the Post lexicon because it’s like a language our app wants to speak.
My first reaction was also “ouch” but it helped to think that conceptually it’s this:
type Post = {
@maxGraphemes(300) text: string,
createdAt: datetime
};
I used to yearn for a better syntax but I’ve actually come around to hesitantly appreciate the JSON. It being trivial to parse makes it super easy to build tooling around it (more on that in the end). And of course, we can make bindings turning these into type definitions and validation code for any programming language.
[H3] #Collections
Our social filesystem looks like this so far:
posts/
├── 34qye3wows2c5
├── 34qye3wows2k3
└── 34qye3wows3k3
profiles/
└── self
The posts/ folder has records that satisfy the Post lexicon, and the profiles/ folder contains records (a single record, really) that satisfy the Profile lexicon.
This can be made to work well for a single app. But here’s a problem. What if there’s another app with its own notion of “posts” and “profiles”?
Recall, each user has an “everything folder” with data from every app:
Different apps will likely disagree on what the format of a “post” is! For example, a microblog post might have a 300 character limit, but a proper blog post might not.
Can we get the apps to agree with each other?
We could try to put every app developer in the same room until they all agree on a perfect lexicon for a post. That would be an interesting use of everyone’s time.
For some use cases, like cross-site syndication, a standard-ish jointly governed lexicon makes sense. For other cases, you really want the app to be in charge. It’s actually good that different products can disagree about what a post is! Different products, different vibes. We’d want to support that, not to fight it.
Really, we’ve been asking the wrong question. We don’t need every app developer to agree on what a post is; we just need to let anyone “define” their own post.
We could try namespacing types of records by the app name:
twitter/
├── posts/
│ ├── 34qye3wows2c5
│ ├── 34qye3wows2k3
│ └── 34qye3wows3k3
└── profiles/
└── self
tumblr/
├── posts/
│ ├── 34qye3wows4c5
│ └── 34qye3wows5k3
└── profiles/
└── self
But then, app names can also clash. Luckily, we already have a way to avoid conflicts—domain names. A domain name is unique and implies ownership.
Why don’t we take some inspiration from Java?
com.twitter.post/
├── 34qye3wows2c5
├── 34qye3wows2k3
└── 34qye3wows3k3
com.twitter.profile/
└── self
com.tumblr.post/
├── 34qye3wows4c5
└── 34qye3wows5k3
com.tumblr.profile/
└── self
This gives us collections.
A collection is a folder with records of a certain lexicon type. Twitter’s lexicon for posts might differ from Tumblr’s, and that’s fine—they’re in separate collections. The collection is always named like <whoever.designs.the.lexicon>.<name>.
For example, you could imagine these collection names:
com.instagram.follow for Instagram follows
fm.last.scrobble for Last.fm scrobbles
io.letterboxd.review for Letterboxd reviews
You could also imagine these slightly whackier collection names:
com.ycombinator.news.vote (subdomains are ok)
co.wint.shitpost (personal domains work too)
org.schema.recipe (a shared standard someday?)
fm.last.scrobble_v2 (breaking changes = new lexicon, just like file formats)
It’s like having a dedicated folder for every file extension.
To see some real lexicon names, check out UFOs and Lexicon Garden.
[H3] #There Is No Lexicon Police
If you’re an application author, you might be thinking:
Who enforces that the records match their lexicons? If any app can (with the user’s explicit consent) write into any other app’s collection, how do we not end up with a lot of invalid data? What if some
15000 chars
SUB-PAGE (https://overreacted.io/introducing-rsc-explorer/) Introducing RSC Explorer — overreacted
[H1] Introducing RSC Explorer
December 19, 2025Pay what you likeIn the past few weeks, since the disclosure of the critical security vulnerability in React Server Components (RSC), there’s been a lot of interest in the RSC protocol.
The RSC protocol is the format in which React trees (and a superset of JSON) get serialized and deserialized by React. React provides both a writer and a reader for the RSC protocol, which are versioned and evolved in lockstep with each other.
Because the RSC protocol is an implementation detail of React, it is not explicitly documented outside the source code. The benefit of this approach is that React has a lot of leeway to improve the format and add new features and optimizations to it.
However, the downside is that even people who actively build apps with React Server Components often don’t have an intuition for how it works under the hood.
A few months ago, I wrote Progressive JSON to explain some of the ideas used by the RSC protocol. While you don’t “need” to know them to use RSC, I think it’s one of the cases where looking under the hood is actually quite fun and instructive.
I wish the circumstances around the increased interest now were different, but in any case, that interest inspired me to make a new little tool to show how it works.
I’m calling it RSC Explorer, and you can find it at https://rscexplorer.dev/.
Obviously, it’s open source.
“Show, don’t tell”, as they say. Well, there it is as an embed.
Let’s start with the Hello World:
Notice there’s a yellow highlighted line that says something cryptic. If you look closely, it’s <h1>Hello</h1> represented as a piece of JSON. This line is a part of the RSC stream from the server. That’s how React talks to itself over the network.
Now press the big yellow “step” button!
Notice how <h1>Hello</h1> now appears on the right. This is the JSX that the client reconstructs after reading this line. We’ve just seen a simple piece of JSX—the <h1>Hello</h1> tag—cross the network and get revived on the other side.
Well, not really “cross the network”.
One cool thing about RSC Explorer is that it’s a single-page app, i.e. it runs entirely in your browser (more precisely, the Server part runs in a worker). This is why, if you check the Network tab, you’ll see no requests. So in a sense it’s a simulation.
Nevertheless, RSC Explorer is built using exactly the same packages that React provides to read and write the RSC protocol, so every line of the output is real.
[H2] #Async Component
Let’s try something slightly more interesting to see streaming in action.
Take this example and press the big yellow “step” button exactly two times:
(If you miscounted, press “restart” on the left, and then “step” two times again.)
Have a look at the upper right pane. You can see three chunks in the RSC protocol format (which, again, you don’t technically need to read—and which changes between versions). On the right, you see what Client React reconstructed so far.
Notice a “hole” in the middle of the streamed tree, visualized as a “Pending” pill.
By default, React would not show an inconsistent UI with “holes”. However, since you’ve declared a loading state with <Suspense>, a partially completed UI now can be displayed (notice how the <h1> is already visible but <Suspense> shows the fallback content because <SlowComponent /> has not streamed in yet).
Press the “step” button once again, and the “hole” will be filled.
[H2] #Counter
So far, we’ve only sent data to the client; now let’s also send some code.
Let’s use a counter as the classic example.
Press the big yellow “step” button twice:
That’s just a good old counter, nothing too interesting here.
Or is there?
Have a look at the protocol payload. It’s a bit tricky to read, but notice that we’re not sending the string "Count: 0" or the <button>s, or any HTML. We’re sending <Counter initialCount={0} /> itself—the “virtual DOM”. It can, of course, be turned to HTML later, just like any JSX can, but it doesn’t have to be.
It’s like we’re returning React trees from API routes.
Notice how the Counter reference becomes ["client",[],"Counter"] in the RSC protocol, which says “grab the Counter export from the client module”. In a real framework, this would be done by the bundler, which is why RSC integrates with bundlers. If you’re familiar with webpack, this is similar to reading from the webpack require cache. (In fact, that’s how RSC Explorer implements that.)
[H2] #Form Action
We’ve just seen the server referring to a piece of code exposed by the client.
Now let’s see the client referring to a piece of code exposed by the server.
Here, greet is a Server Action, exposed with 'use server' as an endpoint. It’s passed as a prop to the Client Form component that sees it as an
4833 chars
SUB-PAGE (https://overreacted.io/hire-me-in-japan/) Hire Me in Japan — overreacted
[H1] Hire Me in Japan
November 11, 2025My sabbatical is soon coming to an end, and I am looking for a new job.
In particular, I am looking for a job at a company that would like to sponsor a working visa for me in Japan, where I’d like to relocate within the next year.
If you can sponsor a software engineering visa in Japan and think I might be a good fit, please email [email protected]. Below I’ll recap some of my past work, with more details re: what I’m looking for near the end of this page.
(Skip to the end)
[H3] #Past Work
Hi! My name is Dan Abramov.
I started programming about 20 years ago and then I couldn’t stop—so I’ve been doing software for over 15 years professionally. I’ve dabbled in different languages, but the vast majority of my recent work has been in JavaScript and TypeScript.
Here’s a few things I have worked on over the years.
[H4] #2025: Consulting
This year, I’ve been doing consulting, so there isn’t much I can say publicly.
Mostly, I’ve been consulting teams using React on how to approach engineering challenges related to performance and state management in complex apps.
On the side, I’ve been contributing to Terence Tao’s Analysis textbook in Lean.
[H4] #2023–2025: The Bluesky app
From 2023 to 2025, I worked on the official Bluesky client app (in React Native). Most of my engineering work focused on improving the app quality, for example:
Implementing animations for the lightbox
Synchronizing feed swipe animations with gestures
Introducing custom lint rules to prevent runtime crashes
Shaving off seconds from Android start time
Some of this work required multi-week deep dives and sprawling refactors.
Rewriting the lightbox to work well on Android
Reworking the cross-platform layout to work well on the web
Revamping how threads show up in the feed
Revamping the post composer into a thread composer
The Bluesky app is open source; here’s a link to my other merged pull requests.
We’ve used a lot of open source software at Bluesky, and sometimes it could be difficult to trace down where a bug is coming from. Occasionally, I’ve had to do deep dive investigations into the underlying projects to file bugs or fixes there.
Reducing the Reanimated serialization traffic
Fixing a 10 year old ScrollView bug in React Native
Documenting the difficulties in getting gestures to work with ScrollView
In addition to my individual engineering work, I’ve done some engineering management and mentoring on the application team. This included:
Helping the team get a natural mental model for working with React.
Mentoring the application team on how to root cause particularly gnarly issues.
Pushing for a closer collaboration with the backend team so that the seams from the client/server organizational split don’t “show up” as poor UX in the product.
I’ve also helped the team explain the AT protocol to a broader community—first in a talk last year, which then crystallized into my recent article called Open Social.
[H4] #2015–2023: React at Meta/Facebook
Before Bluesky, I used to work on the React team at Meta (formerly Facebook). Some of the more visible projects I was involved with include:
The React Documentation, which I co-wrote with Rachel Lee Nabors and others. My work on it included designing the Learn section curriculum, iterating on the Reference page structure, a decent chunk of technical work on the website itself, and much of the actual writing, including the design of examples and challenges.
The public messaging and rollout of React Hooks, including the original documentation for React Hooks and the conference talk introducing them.
Implementing Fast Refresh (hot reloading / live editing) as a first-class React feature. It feels like a distant past, but we used to press Cmd+R to see our edits.
Co-creating Create React App, which ended the “JavaScript fatigue” (allegedly).
I’ve also done some other technical work on React over the years, which mostly consisted of fixing bugs and occasionally revamping the build infrastructure.
Outside of my job, I co-created Just JavaScript, which is a half-book half-course introduction to thinking in JavaScript, aiming to be both whimsical and rigorous.
[H4] #Before 2015
I haven’t done many publicly notable things before getting hired at Facebook, other than accidentally co-creating Redux as a demo for my conference talk.
I’ve previously worked at a small product company that didn’t succeed doing some JavaScript and C#, and before that at an outsourcing firm where I mostly did C#.
I also created React Hot Loader (a very early precursor to Fast Refresh, now built into React), React DnD, and normalizr (which was used by Twitter for some time).
[H3] #Looking Forward
As you can tell from the above, most of my engineering expertise lies in the field of UI engineering, web development in particular, and of course in using React. I’d love an opportunity to share my expertise and to help you create better apps.
I enjoy sharing what I learned, which is why I blog and do talks. Although I prefer when I can work on open source software, this will not be a requirement for me.
Currently I feel most comfortable with JavaScript/TypeScript. I’ve recently picked up some Lean, and working with it professionally seems alluring (if unlikely). I’ve been using LLMs quite a bit recently too and am open to working with them more. In general, I’m open to learning new things on the job (for example, I’ve learned React Native while at Bluesky!) but a new stack may require some ramp-up time.
I care about the quality of what I’m working on, whether it’s an app, a developer tool, or a course. I hope to find a job where caring about quality is appreciated. I know fixing things “the right way” isn’t always possible, but I feel most useful when I’m able to dig into the root causes, and work with others on solving them.
To sum up, I’m looking for a software engineering job… in Japan.
[H3] #Why Japan
Why indeed!
The honest answer is that the feeling of home has moved, and so now I must try to move along with it. I don’t know how it happened exactly. My wife and I first visited Japan a year ago, staying for a few months in Kyoto. After coming home to London, we realized that something was off, so this spring we came back to Kyoto for a few more months. And now we’re back in Kyoto for a few more months again. (Big thanks to the Vue Fes Japan 2025 organizers for covering our recent flights!)
Paying rent in both cities is expensive, flights are disruptive, and we want to adopt a cat, so we have to choose. We’ve loved spending a whole decade in London, but this decade, Kyoto feels right. The question isn’t whether to move but—can it be?
I haven’t learned Japanese yet, which significantly limits my options. I’ve learned hiragana and katakana during the last trip, so now I’m focused on N5 grammar and vocab. I pick up my speed a bit slowly so I expect Japanese to take me a while.
Since I don’t speak Japanese yet and I’m hoping to relocate to Kyoto, I suspect that the most promising option to obtain a work visa will either be an international company with a Japanese presence, or a Japanese company that permits remote work (I assume there aren’t many tech opportunities in Kyoto itself!) and that does most of the work-related communication in English. (I do hope to get to a fluent level of Japanese eventually, but that will likely take me at least a few more years.)
I know there aren’t many options like this, but fingers crossed. I’m talking to a few companies but I would like to get a better sense of the options—hence this post. My hope is to find a real job that lets me come back with a working visa (rather than as a tourist, like now) and to settle down in Japan for the foreseeable future.
If you would like to explore working with me and can sponsor my work visa in Japan, please reach out via [email protected] and let me know!
And if you know someone who might, any leads and intros are very appreciated.
Thank you.
DanFork on Tangled
7982 chars
🛡️ Trust Signals — reviews, proof links, trust-theatre flag (Trust & Proof)
13Review mentions (all pages)
0External proof links (all pages)
PageReviewsProof links
/ (home) 5 0
/a-social-filesystem/ 4 0
/introducing-rsc-explorer/ 2 0
/hire-me-in-japan/ 2 0
🔗 Identity & Technical Layer — schema JSON-LD: identity chains, entity gaps (Identity & Authority)
Homepage — no schema detected (entity gap)
/a-social-filesystem/ — no schema detected (entity gap)
/introducing-rsc-explorer/ — no schema detected (entity gap)
/hire-me-in-japan/ — no schema detected (entity gap)

Your Diagnosis

Before revealing the machine’s verdict, predict the BS score for each signal. Higher = more BS (more fluff, less verifiable substance). Drag each slider, then submit to compare your judgment against the engine.

Information Density 0 / 30
Read the Narrative & headings: do hard facts (prices, dates, numbers) outweigh fluff power-words?
Semantic Coherence 0 / 20
Compare the homepage promise against the sub-page reality. Do they hold the same line?
Trust & Proof 0 / 20
Weigh review mentions against actual external proof links. Claims without verification = theatre.
Commodity Fingerprint 0 / 15
Check headings & narrative against the industry clichés in the setup above.
Identity & Authority 0 / 15
Inspect the schema: is there real Organization/Person identity with sameAs links, or gaps?
Your predicted BS score 0 / 100
💡 Stuck? Reveal the heuristic lens — how the deterministic page-auditor reads each signal (no AI, pure pattern rules)

These are the structural rules a local, deterministic auditor applies — the same lens you can use to judge each signal. They describe what to look for, not this company’s result.

Information Density

Classify each sentence as substantive or hollow. Grounding markers — numbers, currencies, dates, technical units, named entities — outweigh marketing adjectives. When fluff sits right next to hard evidence, the fluff is forgiven.

Semantic Alignment

Pull the main entities out of the H1, then check whether they actually recur through the body. A page that announces one thing and then talks about another drifts. Headings with no real sentences underneath read as pseudo-substance.

Trust & Proof

Count trust words (review, testimonial, rating, verified) against real outbound proof links (Google, Trustpilot, Clutch, G2, Yelp). Lots of trust language with zero verification links is trust theatre. Unlinked logo galleries count against it.

Commodity Fingerprint

Look at how much sentence length varies. Natural writing varies its rhythm; templated or mass-produced copy is statistically uniform. Very low variation reads as commodity content — unless unique named entities break the pattern.

Identity & Authority

Inspect the JSON-LD. Is there an Organization or Person schema, and does it carry sameAs links to real external profiles (LinkedIn, socials)? Missing schema or no identity declaration signals an anonymous entity.

Want to apply this lens yourself? The free BS Indicator Chrome extension runs these heuristic checks live on any page. Bear in mind it is a single-page, deterministic tool — it relies only on pattern rules for the page in front of it and does not perform the cross-page semantic correlation this audit uses, so its readout is a starting lens, not the full verdict.

B
BS Level
Blogs, Influencers & Personal Brands
38.7 Avg BS

Based on 218 businesses audited.

BS Detector

Blogs, Influencers & Personal Brands BS: overreacted (Dan Abramov) (overreacted.io)

https://overreacted.io 📍 Industry: Blogs, Influencers & Personal Brands
5 BS / 100

This is a rare specimen of a zero-bullshit personal brand. It avoids all industry tropes, focusing instead on extreme technical specificity and verifiable professional history. It is a benchmark for what substance looks like in the tech influencer space.

Info Density Power-words vs. Substance ratio.
1
3% BS
Semantic Coherence Homepage promise vs. Sub-page reality.
0
0% BS
Trust & Proof Verifiable evidence vs. Trust Theatre.
1
5% BS
Commodity Fingerprint Detection of industry clichés/templates.
0
0% BS
Identity & Authority Expert verifiability & Schema depth.
3
20% BS

Add JSON-LD Person and BlogPosting schema to formalize the high level of authority for search crawlers. Include a ‘sameAs’ array in schema to link to established profiles like GitHub and Twitter to close the identity gap. Maintain the current ‘minimalist-first’ content strategy as it is the core of the brand’s high credibility.

The site is a textbook example of a high-authority personal brand within the software engineering niche. The content focuses exclusively on deep technical education and career updates, perfectly matching the Influencer/Personal Brand category but with an atypically high substance-to-signal ratio.

“The score of 5 is driven almost entirely by minor technical gaps, such as the absence of structured data (schema_json) and basic meta-descriptions. In terms of content and trust, the site is effectively flawless, representing the lowest possible BS levels for a personal brand.”

Verified Analysis Date: May 25, 2026 © 1EuroSEO Independent Evaluator — Non-Sponsored Result
Brand AI Reputation