Reddit is news aggregate, discussion, and karma distribution site.
Stack
TypeScript, React, and
Redux based frontend with a REST api at
https://gateway.reddit.com/desktopapi/v1/
with its share of accompanying
packages.
On the backend Reddit uses Varnish and Nginx 1.4.6 on Ubuntu.
Some of Reddit’s more notable JS dependencies:
- dashjs
- lodash
- performance-now
- react-intersection-observer
- react-motion
- react-router-redux
- react-router
- react-shortcuts
- react
- redux-thunk
- redux
- reselect
- retry
- raven-js
- superagent
- thrift
- webpack
Reddit also uses server side rendering and pre-populates its Redux store accordingly.
In terms of styling, Reddit uses CSS modules or similar to scope CSS.
API
The REST api is pretty standard with the exception of the response data already
being normalized. So instead of just returning posts: { [key: string]: Post
}
, the api also returns postIds: Array<Post['id']
> along with additional
data such as flair, preferences, permissions, sidebar info, etc., which likely
makes normalization in Redux easier.
When logged in, Reddit makes api requests with an authorization header and bearer token which is extracted from the session cookie.
An additional session tracking id, loid
, is also stored in the session and
sent in the request headers. Reddit also includes the appropriate security
headers.
After successfully fetching data, Reddit will not refetch. Instead it will use
what is stored in Redux (there is an exception for ads). For example, when
navigating to a subreddit, Reddit requests the list view
https://gateway.reddit.com/desktopapi/v1/subreddits/:name
and then navigating
to a post Reddit will request an individual view
https://gateway.reddit.com/desktopapi/v1/postcomments/:id
.
Then when navigating back and forth between the list view and the post, Reddit will reuse existing data instead of fetching it again.
I never figured out what Reddit uses Thrift for. It might be used in their backend between Node SSR service and their Python api and may have accidentally been include in the Webpack bundle.
Redux
In terms of structuring their store, Reddit uses a
combineReducers
setup and has an idiom
of using an api
key with { error: boolean, pending: boolean, loading: boolean
}
for keeping track of loading, pending, and similar states.
Performance Monitoring
The performance api is separate from Reddit’s desktopapi
that is uses for
fetching page data. Instead Reddit makes POST
requests to
https://www.reddit.com/timings/rum
and https://www.reddit.com/timings/perf
with Base64 encoded JSON strings.
It seems that /rum
is only called on initial page load with Performance Api
data and that /perf
is used the otherwise with user analytics as well as more
granular timings for things like React
hydration.
Error Reporting
Reddit uses Sentry and even prints out the current release in the browser console.
Starting Raven release bb4b6f131-production public url https://6b5ce051b2ed4032bd906af3de0630cd@oops.redditmedia.com/11
Ads
Reddit also uses its desktop api for a different kind of content, ads.
The site makes a POST
request with number of ads and the current subreddit
to https://gateway.reddit.com/desktopapi/v1/sidebar_ads
.
The ads are included in the server side rendered page, instead they are fetched through the api on page load.
Timings
Most of Reddit’s api is pretty quick returning in less than 50ms - when there is a cache hit. In the case of a miss, Reddit’s api tends to anywhere from 200ms to 1s. Additionally these misses are more common when logged in, where caching isn’t as effective.