Gatsbygram is a clone of Instagram built with Gatsby v1.
The source code for Gatsbygram lives in the Gatsby monorepo. See the instructions at the end for how to start playing with the code!
It combines the fast performance of static websites with the powerful abstractions, tools, and client capabilities of the React.js world.
Gatsby automatically optimizes your site for the modern web. You provide pages and Gatsby stitches them together so they load as fast as possible.
As proof of this, Gatsbygram loads 2-3x faster than the real Instagram site.
I tested Gatsbygram and Instagram on webpagetest.org using a simulated 3G network and a Moto G4 smartphone—a budget Android typical of many lower-end phones used today. The median speed index score for Gatsbygram was 3151 vs. 8251 for Instagram.
The second repeat view is even faster for Gatsbygram as it now loads from its service worker. It has pixels on the screen in under a 1/2 second on a budget Android device! And for both the initial and repeat view, Gatsbygram finishes loading a full second before Instagram gets started.
The difference in Time to Interactivity (TTI) (measure of how long before the user can actually interact with the page e.g. click on a link) between the sites is just as dramatic. Gatsbygram’s TTI is 6.1s vs 14.1s for Instagram.
As Benedict Evans has noted, the next billion people poised to come online will be using the internet almost exclusively through smartphones.
Smartphones with decent specs (as good or better than the Moto G4), a great browser, but without a reliable internet connection.
Gatsby uses modern web performance ideas (e.g. PRPL) developed by the Google Chrome Developer Relations team and others to help websites work well on modern browsers with unreliable networks.
Sites built with Gatsby run as much as possible in the client so regardless of the network conditions—good, bad, or nonexistent—things will keep working.
Many of the top e-commerce websites in areas where people are coming online for the first time are developing their websites using these techniques.
Read Google’s case studies on:
You give Gatsby React.js components, data, and styles and Gatsby gives you back an optimized website.
Gatsbygram is a completely vanilla Gatsby site. Its optimizations are from the framework.
For Gatsbygram, Gatsby generates over 1000 image thumbnails for responsive images without any custom scripting by leveraging the Gatsby image processing plugin gatsby-transformer-sharp.
Stop wasting time and build something!
All static site generators create a set of files that determine the routing in your site. Typically, you define the output file structure (and thus URL structure) of your site by way of the input structure. For example the input structure:
…would be transformed to:
This is fine at first, but can be limiting. For example, in Gatsbygram, we have
a JSON data blob scraped from an Instagram user profile. From this we want to
generate a page for each image. We couldn’t do this with a typical static site
generator, but Gatsby lets you define routes programmatically through the
createPages API using any data you have available.
Here is how we define pages from our JSON data for Gatsbygram at build time in
Gatsby uses standard React.js components to render pages. When you define a page
createPages API, you specify its component. Those components, usually
called templates, get reused with page-specific data to generate the different
As you can see above, when defining a page, we can set “context” data, which is
passed as a
prop to the component and as a
GraphQL variable in our
query. For the
we pass the id to the post. Below we use that id to query our
and return a fully formed page:
In addition to creating pages for our Instagram photos, we want to make an index page for browsing all photos. To build this index page, Gatsby lets us create pages using React.js components.
These React component pages can query the Gatsbygram GraphQL schema for data and
are automatically converted into their own pages at
about.js is a plain React component with no query.
more complex. It queries for thumbnails for all images and has an infinite
scroll implementation to lazy load in image thumbnails.
Each Gatsby site has a top-level layout component at
layout component is used on every page of your site so can contain things like
your header, footer, and default page structure. It is also used as the
”app shell” when
loading your site from a service worker.
A small layout component might look something like this.
Every page will be rendered as children of the
Gatsbygram’s layout component is somewhat more complicated than most sites as it has logic to show clicked images in either a modal on larger screens or on their own page on smaller screens.
All the setup for this is handled behind the scenes. Gatsby uses @reach/router under the hood but generates all the configuration for you.
Normally page resources are pre-cached with a service worker. But as several
browsers (Safari/Microsoft Edge) still don’t support Service Workers, the
<Link> component pre-caches resources for
pages it links to by loading them into memory.
Gatsby has always had a rich set of lifecycle APIs to allow you to hook into various events during development, building, and in the client.
Gatsby 1.0 adds new APIs and also adds a new plugin architecture. So functionality can now be extracted from sites and made reusable. Most of the new functionality in Gatsby 1.0 is powered by plugins.
Plugins are added to a site in its
gatsby-config.js. Here’s what Gatsbygram’s
config file looks like:
Typography.js is a powerful toolkit for building websites with beautiful design.
Gatsbygram uses Typography.js to generate the global styles for the site helping set the overall feel of the design.
help keep your design in sync as you make changes. Instead of using hard-coded
spacing values (which break as soon as you change your global theme), you use
the Typography.js helper functions e.g.
Together they allow you to quickly iterate on designs.
They also contribute to Gatsbygram’s excellent loading speed. The holy grail of
CSS performance is inlined critical CSS. Meaning a) only ship a page with the
CSS necessary to render that page and b) inline it in the
<head> instead of
putting it in a separate file. There are various tools to make this happen but
they tend to involve extensive configuration and heavy post-processing.
But with Typography.js and Glamor you get optimized CSS with no tedious, error-prone bookkeeping. Typography.js (by definition) generates only global styles so its styles are included on every page. Glamor includes some clever server-rendering optimizations which I’ve implemented in the Gatsby Glamor plugin where it automatically extracts out the CSS used in components on the page being server rendered and automatically inlines those styles in the generated HTML page.
Super fast CSS by default. 👏👏👏
It’s easy to create your own “Gatsbygram” site from an Instagram account.
While writing this post I scraped a few accounts and published their resulting “Gatsbygram” sites:
With thanks to Sam Bhagwatt, Sunil Pai, Nolan Lawson, Nik Graf, Jeff Posnick, and Addy Osmani for their reviews.
And a special thanks to Kristo Jorgenson for his refactor of the “App structure” section.