At Uber, we have hundreds of internal web applications used by developers, product managers, and operations teams—essentially everyone at the company. Since all web applications work differently, it puts additional overhead on our employees to learn how to interact with them most effectively. This can lead to engineers spending a lot of time and effort reinventing the wheel instead of leveraging a universal design system across the company.
To solve these issues, Uber assembled a dedicated design and engineering team to come up with a universal system, which resulted in the Base Web design system. Open sourced in 2018, Base Web is a React component library implementing the Base design language that acts as a device-agnostic foundation for quickly and easily creating web applications.
What is a design system?
A design system is a set of reusable components that, in combination with a set of rules and design tokens (referred to as entities), stores visual design information, like colors or spacing, and enables you to build consistent and accessible applications quickly.
A design system serves as a common language between teams of engineers, designers, and product managers, making it easier or them to work together. It fosters productivity through this shared understanding of building blocks. Design systems also help onboard new engineers and designers—they can quickly go through all the possible components and design tokens used by a given engineering organization.
Introducing Base Web
Base Web is a foundation for initiating, evolving, and unifying web applications. It’s an open source toolkit of React components and utilities that align with the Base Design System–essentially, the designs translated into code. The project is engineered to be reliable, accessible, and extensively customizable.
By contributing our code publicly on GitHub, we are holding ourselves to a high standard and are dedicated to provide an open communication channel for our users where they can suggest improvements and contributions back to Base Web. Each React component is screened by visual regression services on each commit to ensure pixel-perfect layout. We also test updates end-to-end using Puppeteer, a tool that provides high level API control over the Chrome web browser. By leveraging both of these testing strategies, we can rest assured that code changes are meeting product requirements and not causing bugs.
User accessibility is incredibly important to Uber, and Base Web does a lot to ensure developers are given the tools to build products that work for all website visitors. For instance, drag and drop Lists are notoriously difficult to implement because browsers provide little help when developers have to build drag and drop interactions. Developers using Base Web have the peace of mind that keyboard navigation is reliable and works well with screen readers. To ensure additional accessibility, Base Web leverages Styletron, which generates atomic styling so that web applications can download as little content as possible. Styletron is instrumental in optimizing Base Web for users on mobile devices and with poor network connectivity.
To account for the diversity of web applications, we built Base Web to be as customizable as possible. In many ways, you can think of the project as a ‘base’ on which you can easily create new design systems. The project provides a top level entry point to theme all design tokens, including colors, sizing, and typography. Not only can developers easily edit the visual elements of their web applications, but Base Web also incorporates an interface to override functionality.
The overrides pattern
Based on our team’s previous experience working with component libraries, one of our main goals with Base Web was to create web development software that would make it easy to reuse components. To accomplish this, we worked with Uber’s web engineers to detect the main pain points they had to deal with in their day-to-day engineering work. It was clear that having more control over a component was the most desired requirement.
Based on our research, we determined that the main parts of the React components engineers often needed access to were style customizations, the ability to pass through some custom properties to any element in a composable component, like Accessible Rich Internet Applications (ARIA), and the ability to modify the rendering of a component. As a result, we introduced a unified overrides API in the Base Web components.
Some of the benefits we experienced with the proposed overrides pattern are:
- No top-level properties API overload
- No extra properties proxying inconsistently across the composable components
- Easily replaceable presentational components
As depicted above, we provide an identifier for every underlying element in a component so it can be targeted through the overrides property. In the example above, there are two elements rendered and they are exposed as Root and Option in the overrides API.
For every element or component, we provide a way to pass in extra properties and styles, or completely replace the component. Extra properties are passed in as an object that is spread onto the JSX element taking precedence over other properties applied by default. Style overrides can be passed in two ways, as an object or as a function that accepts $theme and some shared component state properties, and returns a style object. The style overrides passed in are deep-merged with the default element’s styles.
We also provide a way to completely replace an underlying element or component by passing the replacements as a component value for the targeted identifier (the Option override is depicted in the example above). This can be useful if you’d like to add or change the functionality of a given subcomponent.
Get started with Base Web
To get started with Base Web, head to our documentation site, and read through the Getting Started section, which covers: