As one of the best remote workplaces globally, we continuously seek new ways to keep Modus Create a family of the best talent in the world. Subscriptions to many productivity tools and services like Slack, Harvest, GitHub, or Google’s G Suite help us do the right thing at the right time. The data we generate through those services is invaluable but fragmented. At Modus Labs, we decided to combine all that data into a single application and bring hundreds of Modites even closer together. We call it Modite Directory.
Modite Directory transparently shows the what, the when, and the where for our distributed teams. We know where people live, travel, when we can expect them to be available, their GitHub interactions, projects associated with, and even their taco stats. Giving tacos in Slack is how Modites recognize team members for their remarkable contributions.
To build Modite Directory as a fast, mobile-first Progressive Web App (PWA) in a time-crunch situation, we explored modern approaches to full stack development. Product requirements demanded all-around performance and quick prototyping, while the engineers sought a cutting-edge development experience.
We committed to a beautiful, modern stack that consisted of:
- React (investigating where React Hooks improve productivity)
- Ionic 4 UI components
- Cloudflare Workers (cloud compute on the edge)
- Cloudflare Access (for the unyielding security)
Cutting-edge, modern Javascript is the common thread in this stack. The sheer wealth of features we are starting with allows us to lower the technical barrier of entry and get on with business logic almost immediately.
This stack also narrows down the technical scope. Ionic 4 web components retain native-like platform UX, allowing engineers the freedom to construct layouts instead of worrying about inconsistencies. Cloudflare Workers make serverless computing effortless, blurring the line between front-end and back-end development.
Create-React-App is Mature, but Better when Customized
Create React App (CRA) has matured into a dependable scaffolding for production-ready React applications. CRA is a great foundation, but minor tweaks may help boost productivity and even improve the performance of the app.
For Modite Directory, we changed the default setup using react-app-rewired to achieve:
- Automated performance budgeting audits with Gimbal
- Moving ESLint and TypeScript checks from Webpack to GIT hooks with Husky to significantly improve rebuild times in development
- Setting up a custom service workers script for better PWA support and offline capabilities
- Better caching for Webpack for even faster builds and rebuilds
- Handpicked removal of unused library modules to decrease the footprint
Mobile UI Prototyping with Ionic 4
Marrying Ionic and React was a satisfying experience to the Modus Labs team consisting of contributors and avid supporters of both frameworks. Ionic allowed us to start producing mobile components quickly and theme them to the liking of our UX team.
Ionic comes with so many useful UI components for mobile development that we enjoyed putting them together to create the experience we wanted. CSS custom properties (a.k.a. CSS variables) make theming simple and build-step agnostic. As an example, real-time dark mode switching becomes a matter of a single media query.
@media (prefers-color-scheme: dark) { :root { --ion-border-color: var(--ion-color-dark-shade); --ion-background-color: var(--ion-color-dark); --ion-background-color-rgb: var(--ion-color-dark-rgb); --ion-text-color: var(--ion-color-light); --ion-text-color-rgb: var(--ion-color-light-rgb); --app-alert-border: #6cf8f1; } }
CSS custom properties allow for an intuitive dark-mode switching in Ionic apps
The Ionic core is entirely dependency-free, thanks to using native APIs supported by the latest versions of all major browsers. It’s carefully bundled with the help of Stencil, which also takes care of many performance-related matters such as:
- lazy-loading of Ionic components
- unused code removal (a.k.a. tree shaking)
- minimal runtime
Ionic 4 Helps Maintain Performance Budgets
Performance is imperative to us, even for an internal application. Users may be accessing the app when commuting, from 30,000ft in the air, or in beautiful remote areas where a cellular connection is limited.
We like to be very pedantic and overzealous to maintain a good practice of loading the minimal resources needed for a user to enjoy a beautifully designed experience. Ionic is an industry leader in getting that right.
The @ionic/react bridge is very light itself, utilizing Ionic 4’s on-demand loading capabilities to the fullest potential. Create React App bundles code with Webpack, which works wonderfully well with Ionic 4 ES modules.
Small application core loads modules on-demand. Service Workers manage just-in-time prefetching and preloading for optimal network usage.
Small application core loads modules on-demand. Service Workers manage just-in-time prefetching and preloading for optimal network usage.
Performance budgets set with Gimbal made sure code commits kept us within the ideal thresholds. Ionic already ships in small chunks, so we didn’t have to worry about splitting it into smaller, lazy-loaded bundles. Webpack Analyzer proved that our bundling strategy was spot-on.
Low-latency Cloud Compute with Cloudflare
The other side of the performance medal usually comes with the back-end APIs. It’s always challenging when an app has to deal with several 3rd party APIs, so we decided to put Cloudflare services to the test.
Cloudflare focuses on security, performance, and reliability, so it already sounds like a natural fit for Modus Create. Moving our DNS registry to Cloudflare was enough to enable CDN distribution with automatic performance optimizations for static resources.
Our priority was combining multiple 3rd party API calls into a single, well-secured endpoint. It also had to be an effortless task, without the additional DevOps work needed. Cloudflare’s serverless compute engine “Workers” rises to the challenge.
Cloudflare Workers is an extension of Service Workers in a custom fork of the V8 JavaScript engine. They are incredibly fast and support the latest version of Javascript as shipped in browsers like Chrome. In other words, engineers can maximize productivity and Development Experience (DX) without the need for a build step or polyfills.
Our Workers scripts primarily combine multiple 3rd party API calls into fewer, mobile-optimized requests. In a way, it was a successful attempt to bridging multi-cloud services on the edge.
Comparable to most serverless implementations, Workers are stateless. Cloudflare’s Worker KV store (short for Key-Value) integrates seamlessly, exposing global namespaces for one or more store instances. KV stores are useful for storing computed data and security tokens.
Notice that KV stores do come with limitations, proving that they are used for state and not as a database replacement. For example, values can be no larger than 2 MB, and each key can perform one write per second. However, Worker KV stores are optimized for high read volumes with low-latency.
The caching layer built into Workers extends native V8 capabilities, adding powerful features controlled by simple APIs. Not only did the caching APIs help reduce time to market, the number of dependencies, and lines of code, but they also helped decrease the risk of reaching 3rd party API rate limits. Such a built-in feature has saved time and resources for our internal web application.
await fetch(requestUrl, { cf: { cacheTtlByStatus: { // longer-term caching for successful responses '200-299': 86400, // minimal caching for missing objects 404: 1, // immediate expiration for failures '500-599': 0 } }, });
Cloudflare Workers add useful caching mechanisms inside the native fetch API
While Workers share similarities with other serverless compute providers like AWS Lambda, there are places where we can easily distinguish the differences. Workers allow a single-file script limited to 1MB in size. They also significantly reduce the effect of the infamous cold start in Lambda, a welcome performance benefit.
You won’t be able to run large server-side applications on Workers (e.g., Express apps) or even import huge libraries. Workers are meant for quick customization of responses on the edge, emphasizing performance, reliability, and security.
Even though each Workers script is a single file, that doesn’t mean that you can’t split your code into nicely organized modules. Bundling a well-defined architecture with Webpack might also help reduce a bit of unused code for better performance. The Serverless framework works wonders in automating bundling and deployment.
Uploading, debugging, and maintenance of Worker scripts is a pleasant and unique experience. Workers features a beautiful editor that you can test without having an account with CloudFlare. We loved that the editor lets us edit and test code on the fly, without deploying. The debugging experience is as comfortable as working in Chrome DevTools (actually uses the V8 debugger in your Chrome), which is particularly useful when debugging 3rd party integrations.
Cloudflare Workers utilize Chromeโs built-in developer tools for debugging
Access Control at the Flip of a Switch
We take security seriously. It’s important to us that we protect any sensitive personal or business information and ensure only the right people have access to it. We also understand that building a consistently reliable security layer takes time and effort.
Modite Directory allows only Modus Create’s G Suite domain account holders. Additionally, some of the data is captured on special devices at our office, which requires secure machine-to-machine authentication. We also wanted to monitor usage statistics and the ability to capture malicious attempts. These requirements call for a complex, multi-layer authentication framework.
Instead of developing a custom solution with Google Platform APIs or services like Auth0, we chose to enable Cloudflare Access. As surprising as it can be to an engineer, it only took a few interactions in the GUI to set up a versatile security layer around our app.
With Cloudflare we get security, compute, and performance out of the box
Cloudflare Access activates before hitting any route or Worker, which means that Cloudflare Access can be used to secure anything accessible via your domain. The integration is incredibly powerful, allowing complex rules to be set up with minimal effort. It took a couple of minutes to enable Google authentication, machine-to-machine communication, special rules for a couple of physical locations, and a full bypass for a PWA manifest that needed to be freely accessed by browsers.
Those few minutes saved us many hours in developing a similar solution ourselves. It also significantly helped with application testing, as we could issue a secure Bearer token to the CI instances. Furthermore, Access provides capabilities of finer-grained user access management and monitoring, something an administrator can use without any necessary engineering skills.
Versatile Full-Stack Environment
Modite Directory proves that great teams can be built at great distances. It also proves that the right choice of progressive technologies like React, Ionic, and Cloudflare’s cloud services can significantly reduce time-to-market. There are many combinations of technologies capable of creating excellent application development stacks, and this one should be high up on your list for cutting-edge PWAs.
Grgur Grisogono
Related Posts
-
React Navigation and Redux in React Native Applications
In React Native, the question of โhow am I going to navigate from one screen…
-
React Navigation and Redux in React Native Applications
In React Native, the question of โhow am I going to navigate from one screen…