Planning a non-trivial web application that utilizes React is something you may have done in the past or are in the midst of doing. This whitepaper documents a high-level process to use when planning a React application, from project organization, collaboration considerations and tooling choices during development, all the way through deployment and performance strategies. There are a lot of moving pieces to creating a real-world application in React, but this guide will help get you started.
- Project Management
- Accessibility i18n and Environments
- Development Process Methodology
- Tooling and Development
- Testing Methodologies
- Codebase Distribution Strategies
- Mobile and Desktop
- Style Guide, Architecture and State Management
- Backend API
- Performance Strategies
Before you write a single line of code, you need to decide how you’re going to get things set up. This typically starts with project management, including discussing and agreeing upon the approaches, tools and services you’ll use to deliver your next application.
To manage the development of any front-end application, consider the following tools to version code, store assets and oversee team member tasks:
|SOFTWARE MANAGEMENT TOOL||EXAMPLES|
|Issues and feature tracker||GitHub, BitBucket, JIRA|
|Distributed version control system (DVCS)||Git, Mercurial|
|Cloud-based DVCS repository||GitHub, BitBucket|
|Document/asset storage||Internal Network, Google Docs, Basecamp, Office365|
|Team communication||Slack, HipChat, IRC, Google Hangouts, MS Teams|
|Task management||GitHub Issues, GitHub Project Boards, Trello, JIRA|
No matter which tools you choose, it’s essential that your team adopt and use the ones you select. Also, don’t be afraid to monitor your use of these tools and improve your workflow if opportunities for improvement arise. New tools are released all the time and you may wish to adopt emerging tools that provide features you find missing in your current process. It’s natural to adopt different tools as your team matures and your application grows.
Accessibility, i18n (internationalization), and targeting the correct execution environment for your app are essential parts of any development effort. More than just what to build, it’s essential to consider how you’re going to build your app, who you intend to use it, and how you’re going to support it. Addressing these considerations at the start of your project will help you clearly articulate how you’ll address key aspects of your app that are ancillary to the code itself, but essential for certain audiences (accessibility and i18n, for instance).
The following table summarizes some of these considerations and provides some helpful resources applicable to addressing them for React-based applications.
|Internationalization / Globalization||UI and UX translations for multiple languages||formatjs|
|SEO||Server-side rendering to enable search indexing||React DOM Server|
|Cross-browser support||If your site must support IE10+ and all modern browsers (Edge, Chrome, Safari)||babeljs|
|Accessibility||WAI-ARIA, WCAG||ARIA, WCAG|
|Offline-first||Service workers||Service Workers|
|Progressive web apps (PWA)||Progressive Web Apps with React.js|
|Cross-platform native mobile app||React Native, NativeScript||React Native, NativeScript|
The resources above are examples for consideration when deciding baseline standards and the types of support your application can offer. There are other approaches and new options crop up all the time. What’s more, if your app won’t benefit from an offline-first or PWA approach, don’t build one in. Always consider the goals and intended audience of your app.
There are a number of different approaches to software development that have evolved over the last 50+ years. Waterfall, Agile, Scrum and Kanban are among the most notable.
Whichever project methodology you select, it’s important to remain consistent, and to ensure that you have buy-in and support from key stakeholders beyond your development team. This includes management, executives and project customers. Some methodologies—Scrum, for example—require active engagement from non-engineering resources. Securing the support of these stakeholders is essential to a successful project.
Tooling has grown in importance among web application developers in the last decade. As the complexity of web applications has grown, so has the variety, scope and scale of the tools developers use to create these applications. In the context of a web application, package managers, module loaders and bundlers, linters, task runners, online collaboration tools and UI frameworks are the key building blocks of developing a robust React application.
Let’s take a look at some of the current popular tooling for React applications.
Package managers help you manage dependencies for an application and ensure that these are available for every environment in which your app will run. For example, npm is often used to fetch dependencies for development, in addition to those needed for production.
Development dependencies are tools that you need during the creation of your app, but which are not required in production. Examples include unit testing tools, code linters or transpilation libraries like TypeScript, which produces your production code assets at build-time, and is not needed in production. Production dependencies are those dependencies that are required for your app to run in production, like React itself, CSS and UI libraries or utility tools like moment.js.
Here are a few tools to consider when choosing a package manager:
Task runners can be used to start a local development server, to compile, minify/uglify assets, run test suites and more. In recent years, webpack has become the de facto standard in the React community, though there are other solid options available.
When working as a part of a team of engineers, a common goal is to ensure that each piece of code authored is written as if it were coded by a single person. The “common voice” idea extends from things like application structure and error-handling, all the way down to formatting and code styles.
There are three types of tools that aid in enforcing a consistent coding style within a team, and should be configured before coding begins.
|Code linters||ESLint, CSSLint, Standardjs|
|Code style checkers||ESLint, Standardjs|
|Code editor formatting/style||.editorconfig|
Online collaboration tools enable you to easily develop and test your ideas. Furthermore, you can easily share your code with others.
Here are a few tools to consider when choosing an online playground:
Building any non-trivial web application is going to require you to create UI components beyond what the browser itself has to offer. Textboxes, labels and dropdown lists will only get you so far.
When it comes to UI components, there are a lot of solid options, both open source and commercial. The key is to pick a library that is built on React and uses React APIs, not one that merely wraps React. Wrapper libraries will provide a familiar syntax, but you often lose many of the performance and functional benefits of React when implementing these libraries.
|KendoReact||Native React UI component library that includes grid, charts, dropdowns and many other customizable components.|
|Material UI||An open source library containing many of the components needed to create applications which adhere to the Material Design specification.|
|Semantic UI||Official React components for the Semantic UI framework. Designed to help create responsive layouts with “humanfriendly HTML.”|
|React Bootstrap||React components for this popular CSS framework that is often used for application layout and its popular grid system.|
How you test, the tools you choose for testing and the ways you decide to implement tests is less important than the fact that you prioritize some form for testing in your application. It’s likely that you’ll want to test each module or unit of your code with unit tests. As you start to string code units together into a complete application, you’ll want to consider functional, endto-end testing. The list below contains some popular unit and functional test tools for React applications.
|Jest||The Jest testing framework is a zero-configuration test framework that works out of the box with React applications|
|Karma||The karma test runner is ideal for writing and running unit tests while developing the application. It can be an integral part of the project’s development and continuous integration processes.|
|Navalia||Navalia is an end-to-end test-runner and browser automation framework with a simple API and support for complex user interactions.|
For your own application, you need to consider both your initial target and any future platforms on which you’ll want to serve your app.
If your app will only run in a browser, then your strategy is simple: deploy to a single server environment and your code will be served to the browser like a traditional web app.
If you’re considering targeting mobile devices or the desktop for your app, here are some tools to consider for leveraging your React codebase on non-browser platforms:
Progressive Web Apps use modern web capabilities to deliver app-like user experiences, particularly on mobile devices. They evolve from pages in browser tabs to immersive, top-level apps, maintaining the web’s low friction at every moment.
Some of the key characteristics of PWAs include:
- Progressive - Work for every user, regardless of browser choice because they’re built with progressive enhancement from the start
- Responsive - Fit any form factor, desktop, mobile, tablet, or whatever is next
- Connectivity independent - Enhanced with service workers to work offline or on low quality networks
- App-like - Use the app shell model to provide app-style navigation and interactions
- Fresh - Always up-to-date thanks to the service worker update process
- Safe - Served via Transport Level Security to prevent snooping and ensure content hasn’t been tampered with
- Discoverable - Are identifiable as “applications” thanks to W3C manifests and service worker registration scope allowing search engines to find them
- Re-engageable - Make re-engagement easy through features like push notifications
- Installable - Allow users to “keep” apps they find most useful on their home screen without the hassle of an app store
- Linkable - Easily share via URL and not require complex installation
React has a lot of features that make creating PWAs easy.
When you’re ready to start getting your application closer to test, staging or production environments, you need to plan for regularly moving your code between environments. A continuous integration (CI) server is the ideal solution for managing your deployments, regardless of whether you intend to deploy to a live environment with every push.
Setting up for CI also improves your approach to local development, especially when you think about your CI approach from the start. Ideally, anything you do during CI you should first do locally to ensure that other developers on the team can easily replicate your setup, and that your CI system is properly configured to obtain dependencies, run tests and the like.
For React applications, I recommend considering one of the following CI tools:
This is one of the most commonly-skipped steps in the creation of web apps, but should not be overlooked. A quality tool, like one of the tools below, will save you countless hours tracking down production issues that are difficult to replicate in a local environment.
Defining a style for your team and project is essential, as is deciding the architectural styles you’ll implement.
As a mature application framework, React is very opinionated about the guidance it provides and the patterns you’re encouraged to use. Before starting your React application, consider a careful review of the Thinking in React guide for some pointers, recommendations and common patterns to consider. Doing so will help you scale your app as it becomes more mature and well-trafficked.
State management is built into React via component internal state and can be shared between components via Props. For more complex state management, I recommend considering a library like Redux or MobX, both of with can easily be plugged into React applications and used to manage application state and mutations.
|React State & setState()||Native React mechanisms for managing the internal state of a component and batching updates to view elements that depend on that state|
|Redux||Robust state container that lives apart of React components and can help manage complex application state|
|MobX||Simple state manager for React apps. Preserves some of the concepts of Redux, but is a bit simpler to start with|
When building your web application, you’ll want to make sure you consider data storage and access from the start. Even if you’re working with an existing data repository, I highly recommend wrapping that store in an API and taking an API-first approach to your development project.
API-first development means that you document, build and test your API first. The end result is a relatively-stable API before you write any dependent application code. This doesn’t mean front-end development has to wait, however. During API construction, front end developers can build prototypes as early consumers of the API and provide valuable feedback to API developers.
The strongest argument in favor of API-first development is to reduce the chances that API bugs or weaknesses end up propagating into or are amplified by the data later. As much as possible, you don’t want your front-end to have to bend over backwards to work around or mask deficiencies in your API later. Having a documented and solid API before a line of production code is written can go a long way to saving you headaches in the future.
So build your API first. Document it, test it and be ready to evolve it as you build against it.
A few key details to remember when taking an API-first approach is that security and authentication need to be embedded in the API, and that data environments should be kept separate. When developers are coding against the API, they should be working with development data, never live production resources.
It’s worth investigating how to get the most out of your React application—from a performance standpoint—early-on in the development process. Let’s investigate some ways that you can ensure that your app runs well once you get it live.
|babel/preset-env||An npm extension to Babel that allows you to specify the browsers and versions you want to support; ensures that Babel transpiles your source to code required by the browsers you support.|
|Polyfill.io||A utility library that loads polyfills at runtime when a user visits your site or app. Polyfills loaded are only those needed by the browser, meaning that modern browsers won’t be hit with the network cost of downloading code they don’t need.|
Tree-shaking allows you to remove unused imports from your codebase, thus reducing the size of your bundle and the final assets shipped down to the browser.
Lazy-loading is an approach that loads dependent modules only when you need them. For instance, an About component on a Home page would only be fetched when the page is accessed by a user. This keeps initial application payloads small and speeds up the loading experience of your app. While React does not provide lazy-loading capabilities by default in its core API, it is possible to use Promises or npm libraries to implement this functionality, should you decide to do so.
React is one of the hottest new web technologies, and there is a rich ecosystem of tools and libraries to support it. The strategies we’ve presented here for tooling, testing, performance, style and distribution will help you get started on the path to success. Once you have mastered the basics, there is a rich and diverse set of tools, libraries and methodologies for you to explore.
React seems like a cultural issue that changes from continent to continent. There are a lot of people who criticize and really love.
Take care of yourselves. Also, do not forget to comment and leave a reaction. :)