6 min read

Contributing to the React Native documentation rewrite

In 2019 Meta opened an umbrella issue to rewrite the React Native documentation. I picked up four of the API pages. The most-used component in the framework had shipped its accessibility props without documenting them.

DocumentationOpen sourceIssue triageAccessibility

In May 2019 Christoph Nakazawa opened an issue on the React Native website repo titled "☂️ Website Redesign and Documentation Rewrite". It said what most people using the framework already suspected: a lot of the docs were written in 2015, and they no longer described what building a React Native app was actually like.

Underneath was a checklist. Around sixty component and API pages, each with an empty box next to it, each waiting for someone to open the source file in the main repo, read the props it really accepted, and make the Markdown match.

I picked up four of them.

The instructions were unusually specific

Most issues asking for help are vague about what help means. This one wasn't:

if you'd like to ensure consistency for the ScrollView component, it's best to go to the react-native repo and look for the ScrollView.js file. Then go through the ScrollView.md documentation in this repository and compare each prop that it accepts and update the .md file in this repo.

So: diff two files across two repos, by hand. It sounds like the kind of task you'd give someone to keep them busy. Then you actually do it and find what's been sitting in the gap.

Text was missing its accessibility props

I started with text.md, because Text is the component every React Native app uses on every screen.

The page listed nineteen props. The component accepted about thirty. Among the ones that had never been written down were accessibilityRole and accessibilityState — the two props you need to tell a screen reader that something is a button, or a heading, or currently disabled.

Think about what that means in practice. A developer sits down to make their app work with TalkBack or VoiceOver. They open the docs for the component they use more than any other. There is nothing there. As far as the documentation was concerned, React Native's Text had no accessibility API at all.

It did, of course. It had shipped, it worked, people at Meta were using it. It just wasn't findable by anyone who learned the framework the normal way, which is by reading the docs.

The same page was also missing onTextLayout and the whole set of gesture responder callbacks — onStartShouldSetResponder, onResponderGrant, onResponderMove and the rest. Not exotic APIs. The ones you reach for when you want to handle a touch yourself instead of wrapping everything in a Touchable.

statusbar.md had a hole of the same shape. It documented setBarStyle, but not pushStackEntry, popStackEntry or replaceStackEntry. Those three are how you set the status bar for one screen and put it back when the user navigates away — which is exactly what you need in any app with a dark screen and a light screen, and exactly what you'd never know existed.

Sorting the props wasn't busywork

All four of my pull requests start the same way: sorted the props into alphabetical order. On the ActivityIndicator and KeyboardAvoidingView pages, that reordering was the whole change. Nothing was missing on those two. I moved some lines around and that was it.

It looks like the definition of a trivial contribution, and I'd still argue for it.

The old order wasn't an order, it was a history. Props sat wherever they landed when someone added them. selectable was at the top of the Text page for no reason except that it got there first. backgroundColor sat in the middle of the status bar props, between hidden and translucent. If you wanted to know whether a prop existed, you read the entire list and hoped.

Sorting turns that into a lookup. And it makes the next comparison against the source cheap — two alphabetical lists sit side by side and the gaps just fall out. That's the part that mattered. It wasn't tidying done on top of the real work, it was what made the real work quick enough for the next person to bother doing.

Why the docs drifted

Nobody deletes documentation. It goes stale because a prop gets added to a JavaScript file in one repo and the Markdown file in the other repo has no idea it happened. Nothing breaks. No test fails, no build goes red. The gap opens quietly and grows with every release, and the only way to see it is for a human to sit down and read both files next to each other.

The 2015 docs weren't badly written. They were accurate the day they were published. Four years of shipped features piled up on top of them without anyone recording it, until there was enough that Meta had to open an umbrella issue to dig back out.

Which is why the checklist is the right shape for this. The problem isn't difficult, it's wide. Sixty pages of boring comparison. That doesn't need one person being clever, it needs a lot of people each giving it an evening.

Most of it was the issue tracker

The pull requests are the part you can see. Most of the time I spent on that repo went into issue threads instead.

That work is mostly asking one more question. Someone reports the internal doc links are broken, I follow their steps, can't reproduce it, and say so — now we know it's something about their setup rather than the site. Someone reports that react-native run-android fails, and the command in the report has a space in the middle of it. Someone opens a pull request called "sorted in alphabetical order", and I ask them to put the filename in the title, because a maintainer scanning fifty PRs shouldn't have to open one to find out which page it touches.

None of that shows up anywhere. It's still what keeps a tracker readable, and a readable tracker is the only way maintainers ever get to the reports that matter.

What I'm taking from it

The thing I keep coming back to is that an undocumented API doesn't really exist. accessibilityRole shipped and worked long before it appeared on the Text page, and for everyone learning from the docs it may as well not have been there. Writing it down was what made it part of the framework.

And drift like that is structural, not a discipline problem. Any setup where the API lives in one file and its description lives in another will come apart eventually, because nothing holds them together. Being annoyed at contributors for not updating the docs misses the point — they're not being careless, the two files simply have no idea the other one exists. If I ever ship a library of my own, I'd want the reference material generated from the types rather than written twice. A link that isn't mechanical won't survive a busy release week.


My four merged pull requests are #945, #978, #982 and #990 on react/react-native-website. Plenty of boxes on that checklist are still empty if you want one.