Why I can't live without review apps

As an architect, I think a lot about development workflows. Ever since I read Product Development for the Lean Enterprise many years ago, I can't help but see the process of software development as one big assembly line that needs to be constantly evaluated and optimized.

How quickly can we start a new project?

How quickly can we iterate on UI during local development?

How long does it take to get feedback from your team?

This last question is where review apps are incredibly powerful, so much so that I can't live without them.

What are review apps?#

Review apps, sometimes referred to as "previews" or "deploy previews" are ephemeral versions of an application, typically deployed from a branch on GitHub or another version control system.

Review app

Where to find review apps#

Most modern hosting providers provide some flavor of this capability.

Vercel supports Previews.

Heroku has Review Apps.

Netlify offers Deploy Previews.

...and so on.

Some definitions of review apps may vary, but in my experience review apps are:

  • Deployed from branches: You don't need to merge your code to your master/main branch in order to deploy.
  • Independently addressable: You can access on a separate domain or subdomain for web apps, or as a separate app download for mobile apps.
  • Shareable: You can send a link or download to anybody you choose.
  • Ephemeral: They are temporary, often destroyed after a branch is merged into master/main or after a period of time.

How do review apps work?#

The exact implementation of review apps depends on your hosting provider. In my opinion, Vercel has the most elegant solution for review apps (they call them previews) so we will look at their solution more closely. Vercel designed their system from the ground up to support previews, hence why you see Deploy. Preview. Ship. in massive font on their home screen. Heroku, on the other hand, added their review apps to an existing system so their solution does feel a bit more shoe-horned and complicated. In either the case, the same principles apply.

Enabling review apps in version control#

Vercel previews are enabled by default when you enable the Vercel GitHub integration.

Below is a screenshot of the GitHub integration settings for the GitHub project that powers the site that you are on right now, seanconnolly.dev.

Vercel GitHub

After I write this sentence, I am going to pause writing to commit and push my changes to GitHub so you can see what this blog post looks like as a Vercel preview.

Below is a screenshot of what my VS Code IDE looks like right now. In the bottom right, I have a terminal open where I am about to commit my changes and push to GitHub.

VS Code screenshot

In GitHub, I created a pull request for my current branch. With the Vercel GitHub integration enabled, I am able to see this convenient "View deployment" link.

View deployment

Clicking the "View deployment" link navigates me to https://seanconnolly-r0nt71a73.vercel.app/, the URL for the preview. If you click the "Why I can't live without review apps" heading, it will take you to the earlier version of the blog post you are reading, including my TODO reminders and probably some typos 😛.

Review apps with backend services and APIs#

Review apps work best when the frontend of your application is stateless, meaning it doesn't ship with a tightly coupled stateful data store.

If you did include a data store with your application, anytime you created a review app, meaning a new version of your application, you would also need to copy some or all of the data store. This can be a time-consuming and costly endeavour, depending on the size of your data. There are many other reasons to keep your frontend stateless, and in some cases, like with mobile apps, your frontend is stateless by design. In any case, because I can't live without review apps, I always work with stateless frontend applications.

So, how do we interface with backend services and APIs?

There are a number of ways to structure your environments to work with review apps, but my environments normally look like this:

Review app environments

This is for the smallest use case. With larger team projects, there could be multiple static environments like development, staging, test, etc. and those may also have their own backend APIs. The point here is that your review apps are not expected to have their own copies of your data store and API. Instead they piggyback off of an existing data store that you are already using.

Review apps with automated tests#

Automated test frameworks like Cypress allow you to run your tests against a specific URL. Often you will run these tests locally by pointing Cypress to a localhost URL like http://localhost:3000. You can also run your tests against your production environment or another static environment like dev or staging. With Cypress you can set the CYPRESS_baseUrl environment variable to dynamically run your tests against a review app, which as we saw before has a dynamically generated, unique URL. I'll skip the gory details of how we do this in CircleCI, our continuous integration tool, but effectively our Cypress run command looks like this:

CYPRESS_baseUrl="https://seanconnolly-r0nt71a73.vercel.app/" npm run cypress

While there are many ways to run Cypress in CircleCI and other continuous integration tools, our goal is to run our automated tests in an environment as close to the production environment as possible and we find review apps are the best way to do that.

Review apps for teams#

Review apps really shine with cross-functional teams. My team's Clubhouse stories usually look something like this:

Clubhouse story

And our team workflow has these steps:

  • Ready for Review
  • Ready for QA
  • Ready for Design Review
  • Ready for Product Review

(I removed a few other steps that aren't relevant to this post)

That's a lot of reviews! At each stage, a teammate has an easy way to access the review app and verify whatever they need to.

In Ready for Review, other developers can pull up the review app to check certain types of functionality or to confirm whether or not the code they are reviewing actually results in some kind of defect or odd user behavior. Without review apps, reviewers would need to pull down the branch and run it locally, which is fine, but in my experience is more effort than people care to go through so they often just don't do it.

Ready for QA is the most necessary use of review apps for us. QA engineers perform almost all of their tests on review apps. This is also the area where we see the most iteration cycles. When QA finds a bug, the developer needs to track it down locally and then push those changes to their branch, resulting in a new deployment for QA to re-test.

Ready for Design Review is applicable when working on larger new features or making significant design changes. Designers don't usually go through the steps to run the app locally so I've often seen teams ship their work to production or a shared development environment in order to get design feedback. Review apps allow design iteration to happen before code gets merged with the main project.

Ready for Product Review is where product owners decide whether or not a feature is ready to go to production. Like designers and QA engineers, they benefit from having easy access to the application in a near-exact replica of production before the feature is exposed to real users.

Though your team may not follow all of these steps in the exact same way, hopefully you can see how many members of your team can benefit from review apps.

Review apps for indie hackers?#

When I say I can't live without review apps, I mean it. Even in small projects where I am the only developer, I use review apps extensively. Even with this blog, there are plenty of use cases where review apps come in handy.

As a member of the Blogging for Devs community, I am constantly posting review app links in the community to get feedback on my posts before they are exposed to readers and search engines.

I also participate in community writing programs where I am writing on behalf of companies like LogRocket and Fauna. Their editorial process is more rigorous and I find it most effective to share the review app version of the post that I plan on publishing because it is the most realistic preview I can provide to editors.

Also, my blog is a side project. I often work on cosmetic or structural changes to the site and I like to be able to test it across multiple devices and browsers without much fuss. The easiest way for me to test things is to push to a branch and open the review app link wherever I want to test. Redeploying to review apps is as easy as running git commit -am "Fixing mobile issue" && git push, waiting just a minute and refreshing.

What review apps mean for production deployments#

By adding review apps to your development workflow, production deployments become substantially safer and faster.

For smaller projects, as soon as I confirm my changes look good in my review app and my automated tests pass, I will merge to master/main and walk away knowing production will be updated momentarily.

For projects with a larger team, a lot of verification happens before merging to master/main so by the time a branch is ready to go to production, there is a very small chance that anything goes wrong in our continuous deployment pipeline. That said, I generally err on the side of caution when working with products that real people are actively using and paying for so I advocate for running automated tests again and also including some manual verification steps.

If you are inclined, you can also incorporate review apps into your continuous deployment process where your workflow looks more like this:

Production review app

  1. This is production steady state where the production domain points to the current version of your app.
  2. Next, the review app is deployed but only accessible via its unique URL. You can use this for automated testing, manual verification, etc.
  3. Finally, you can change the domain routing to point to the new version of the application, promoting the review app to production.

Why I can't live without review apps#

When I wrote about build and release process in my Flutter vs. React Native article, I noted that Expo has a similar capability to review apps where you can publish and share previews of your native application.

I know some people avoid Expo for its various limitations, but if I were to start a React Native application today, I would definitely reach for Expo until its limitations became a limiting constraint. That's how strongly I depend on review apps.

For me, it comes down to one simple word:

Feedback

Get as much feedback as possible from as many people as possible in the shortest time frame possible.

Review apps maximize the amount of feedback you can get on your application before you ship it to real users and that is something I cannot live without.

What about you? Are you using review apps in your workflow? Join the newsletter below 👇🏻 and let's chat.