Building Sustainable Design Systems: T. Rowe Price's Web Standards-first Approach

May 163:25 pm – 4:00 pmStage: Main StageTalk
Slides

Checking session availability…

Hang tight while we load the latest updates.

Are you searching for ways to ensure your design system stays relevant in the ever-changing digital landscape? Join T. Rowe Price's Beacon Engineering Lead as they share their insight on building a design system using a web standards-first approach.

  • Discover the reasons behind their decision to pivot away from developing for multiple frameworks used at the firm and towards a more streamlined solution.
  • Learn how utilizing browser standards such as web components, CSS variables, and more have helped increase throughput, consistency, and accessibility.
  • Don't miss this opportunity to gain valuable insights and strategies for creating a design system that remains adaptable while providing delightful customer and developer experiences.

Building Sustainable Design Systems: T. Rowe Price's Web Standards-first Approach

Alex Wilson at UXDX USA. Video: https://youtu.be/fxPfNx2KUWM

Readable transcript: edited from the recording's captions for readability (fillers and false starts removed, punctuation and section headings added). Wording is the speaker's own. Timestamps are positions in the video. Names marked [?] could not be verified against the audio.

Three ways to distribute a design system

[00:00:00] Today we're going to go over how to build sustainable design systems like we have at T. Rowe Price. We've taken a web standards first approach and I'd love to share that with you. Today we're going to go over some common design system distribution patterns, T. Rowe Price's design system journey, our web standards first approach, challenges and considerations, and our results.

[00:00:22] Diving right in, there are three real ways that you can distribute design systems right now from a technical perspective. When you see framework throughout this presentation, I'm talking about JavaScript frameworks. You can use a single framework to create a design system, multi-frameworks, or you can go the framework agnostic route.

[00:00:43] The single framework pattern is one where you have company-wide adoption, everyone sold on a single framework. Maybe that's React, maybe it's Angular, Vue. Some of you have probably heard some of these frameworks out there. There's really a lot of technical familiarity that you need in order to have a design system that's only focused on one framework, but this works really well for startups, small companies and even larger companies that have a very rigid governance structure.

[00:01:11] And then there's the multi-framework pattern. This is where you might have segments of usage, maybe you have pockets using Angular, pockets using React, other pockets using Vue, but overall you have a good idea of where you're going and these are the frameworks that you're going to stick with. There are companies out there that definitely focus on this approach. You've got IBM, you also have Adobe that's on it, and we've actually done it at T. Rowe as well.

[00:01:34] And then there's the framework agnostic approach, and I really like this one. This is where you still have segmented framework usage but the company embraces change. They don't really have a set idea of whether or not they're using React or Angular or Vue, but they're willing to change as the times change, because we know that technology is always improving and so we can't put all of our eggs in one basket.

The first iteration of the Beacon design system

[00:01:58] That leads us to the Beacon design system at T. Rowe Price and our first iteration. In our first iteration, in a pre-design system landscape, we had many internal component libraries. Teams had this idea to share code, which was fantastic, but they were doing it in a way that was still siloed. You had frameworks that they were building for with these libraries, they had some with React, some with Angular. You had pockets within departments and other pockets in other departments where they were not even communicating. The associates were looking for a way to share these things but on a more global scale, as well as the designers. Everyone saw this need, and they also saw the need to build a design system without even saying it. They didn't know what a design system was, and this was at the point where design systems were still kind of making their way up in the industry.

[00:02:48] When it came time to actually build one, we decided to plan for our consumers, and we have four main consumers. We have developers of course, we have our A/B testers, we have our content authors. We use a product called Adobe Experience Manager and we have to create those authoring experiences that are associated with the UI so that an author can go in and add content as they need to. As well as our end users, so we need to make sure that the components and all the code that we're building is performant, accessible, and delights the end user at the end of the day.

[00:03:22] When we finally kicked off, we internally open sourced the build up, and by that I mean that we started getting developers from across the different organizations finally talking with each other, getting in one room, and started contributing the components from each of their libraries into a centralized place. We then centralized those components around design tokens for theming, so that way when our designers provided the designs for each of these components we had a way to style them without structuring the components in a way that they couldn't be changed later. Design tokens is of course a really hot topic in the design space, but it's something that we also have on the tech side and I'll get into it a little bit. We also formed a team to manage and improve this system. We started with just a single developer but have quickly grown and we're now up to seven.

[00:04:17] While this worked well for a certain period of time, we had some lessons learned. We realized that maintaining the technical standards was really challenging. We knew that there were also really hard complications around feature parity, because you'd build something in React and then you try to build it in Angular, maybe the features weren't there in Angular that were in React, or vice versa. So then you had to make sure that you're keeping up with the developer experience that the consumers were expecting. If they were expecting to be able to use certain features of React, we should make sure that those are available for them to use.

[00:04:50] The maintaining of strong developer experience feeds right into that. If we can't focus on a single framework, or if we are spreading ourselves too thin, then we can't focus on those that are actually using the components in their day-to-day work. And then finally, managing library versions became super challenging, because we'd have to make sure that the version of React that we had in our repo still covered all of the features that people were using from legacy versions of React, same with Angular and the other frameworks that we supported.

The web standards first pivot, and what web components are

[00:05:23] This brought us to the point where we needed to have a crucial pivot. We needed to make some change based on all these learnings, and that change led us to our web standards first architecture. This is one that I'm really proud of, that we've really worked hard on. Here we offer native web components that are functionally supported by the web specifications and themed with design tokens. We kept those design tokens around but we changed the vehicle by which we send the design system out to our consumers.

[00:05:53] Now you might be wondering, what are web components? They're made up of four different technologies. I won't dive too deep, but they're custom elements, HTML, shadow DOM, ES modules. I mention those because I'm going to be referring to a couple of these throughout the deck. These provide native browser support. So when you're building a component, you build it once and you can drag and drop it on the page without any additional build steps, because the browser actually knows how to interpret that component after it's already been built. You don't need to have a complicated build step right before it goes out to a live page.

[00:06:30] And then there's framework compatibility. Since the browser supports these features, the frameworks that are built around them automatically support them as well. So we can build a web component and it can be used by an Angular developer, because Angular supports the web standards and the web component follows web standards. We get style encapsulation, and that comes with the shadow DOM, and a clear and familiar API that developers can use, because the components, the way that they're structured and the way they're intended to be used, are very, very similar to HTML elements. So if you've used HTML or CSS then you should be able to use these web components. The exciting thing for all the designers in the room is, if you know a little bit about HTML and CSS and your company is using web components, you could actually build some of these experiences without having to have a lot of developer workflow. You can do it on your own, so I think that's pretty exciting.

The supporting technologies behind our web components

[00:07:30] Next we have the supporting technologies behind all of our web components. We follow the web specs pretty rigidly. We use HTML spec features like the different semantic HTML elements: dialog, input and button. Each of those elements actually provides features that we don't have to build on our own, and they provide accessibility features so we don't have to include those as well. So why not use them over using divs, spans, other things that don't make sense in the context of an HTML structure?

[00:08:00] Next we have CSS specification features. Here we're using CSS grid. Now we could have chosen to use something like Tailwind, or if you recall a few years ago where Bootstrap was in its popularity, there was also Foundation. A lot of those provided style frameworks so you can create your own grid. Well, the web learned along the way behind the scenes and they came out with CSS grid, and that's what we're using now to structure the look and feel of our components. We're also using CSS variables to theme our components dynamically, and flexbox to adjust our layout.

[00:08:37] When we get into JavaScript, of course there's plenty of JavaScript for us to use in there, but I want to call out a few examples. We have Intersection Observer, Mutation Observer, both of which we use within our components to understand the interactivity around the component, how that end user works with it. Instead of building our own using a third-party library, we come here first. This isn't to say that we never use libraries. We're actually using a library called Lit as the boilerplate for our web components, but we do focus on this and make sure that we prioritize this first over those abstractions.

[00:09:10] And then finally, design token spec features. Design tokens are just a way for us to structurally understand designs and apply those designs to our components without baking them into the components themselves. This allows us to switch the color dynamically on the web page, so that way, if you have a dark and light mode button and you click that, everything changes all at once. I'll show a little bit of an example at the end if you're not familiar, but that's the overview.

Our new workflow: investigate, architect, build, integration test

[00:09:42] With all of these features we have a new workflow. That workflow consists of an investigation stage, architecture, build, and integration test. In our investigation stage we do a lot of scouring of the web, feel out what people are building, how other design systems have taken care of similar problems. We also really focus on the W3C, so we go there. They've got a whole revamped site, plug for W3C, but you can search in there, find all the different features. Here I was just looking up grid, you can see it coming up there, and then you can just see what's possible.

[00:10:19] Next we spend a lot of time with our architecture. We get the designs from our designers on the tech side of our design system, and from those designs we come up with a complete architecture that caters to our users. So we come up with our content model, how those authors are going to interact with the components that we build. We also come up with the API, so how will the developers interact with the component. We even go as far as to write a sample HTML structure for our component, to make sure that we're following the semantic HTML standard, and that way it doesn't come out with just divs at the end.

[00:10:57] There are a lot of other things that we put in there, and if we have any third-party libraries that we are using, we do make sure to mention them at the bottom. It is important to note that this isn't just within our team that we're doing this, and we're just focusing on making sure that we're getting the product through. We're also sharing this with the community and the designers, so that way they have a better idea of how the component works and they can provide feedback as well.

[00:11:22] Next we have build. This step is pretty straightforward, we build the component based on the architecture, but we recognize that changes may come, so if the architecture needs to be changed we make sure to update that. After we build, we deploy it, but all of those docs are considered assets of our design system. We put them out there, we put them in our, we're currently using Storybook, we put them in our Storybook, in our documentation tool, and then we make them available.

[00:11:49] And then finally we have the integration testing stage. This stage is not critical for us because we know web components can be used across frameworks, but what we do want to know is, what's the developer experience like? Is it really strong or is it something that kind of just passes? So we go into a basic React app, an Angular app, AEM, Adobe Experience Manager, and just straight HTML, and use the components, eat our own dog food if you will, and then just test them out to make sure that they're working as expected.

Example one: the modal, CSS grid and semantic HTML

[00:12:20] All right, let's dive into some examples. The first one is the modal example. For the modal example we're going to go over two main topics: CSS grid for layout, and then also the semantic HTML. For this modal we are using the dialog HTML element. This HTML element automatically comes with features to open and close, it comes with baked in accessibility and the ability to transfer data back to the window. Again, we could have used a third-party library for this, but the web supports it so we use the dialog element.

[00:12:55] Next we have CSS grid. I've already mentioned the basics of that and what it provides, but an important thing to note is that it also provides item placement and ordering, and this is a key feature of how we make this modal more flexible than your average modal. We know that we have some strict guidelines around how developers and designers should work within the design system and how we want it to look, but we also want to spark innovation. We want teams to still try new things, so we don't want to make our components too rigid that they can't do that.

[00:13:25] With this item placement, we can see that we have the media zone up top, the title comes next and the content comes below. Using CSS grid we can dynamically change the ordering of this, and you can see here, if the developer passes in a new order of title, media and then content, it switches the look and feel of the component, so that way it can work in those cases where our initial implementation may not have.

Example two: form fields, element internals and theming

[00:13:54] Next we get into form fields. For form fields we're going to go over the element internals API briefly, and then also the CSS variable usage that we have within our forms. The element internals API enables our components to work with native HTML elements. By that I mean that if we take a look at this example here, we can see that we have input fields, a dropdown, we've got some error messages, some radio buttons, and they're all wrapped within a native form element.

[00:14:27] If we were to build our own form component, all of our developer consumers would have to bring that in. They'd have to make sure that it worked with their current system, and we know that many teams already have their own structure for how they want to build forms, and then make sure that it works without fail. With this approach, using the element internals web API, we're able to connect with the native form elements, which means that the elements and the components that we have here can be used within any form that already exists. We're in a state where T. Rowe has been around for quite a long while, so we have a lot of legacy systems. This is really important for us, to make sure that it works with those legacy systems.

[00:15:09] Next we have theming. We use CSS variables throughout all of our components, that's how we drive the theme, so everything from the text to the border to the color of the background, it's all driven that way. But that leads to flexibility in the way that that theme can work. So if you have a company that maybe has brought in a new company, maybe there was a merger, now you can use the same components, theme them a little bit differently using overrides, and then they'll still work just as expected. The functionality is baked in but the theme is dynamic.

[00:15:41] Our plan, using design tokens, is to generate these CSS variables, and we plan to connect those design tokens with our design products. We're hoping that Figma comes out with their design token solution, but there are many other opportunities out there for us to connect with our design partners. You can see there the different change in theme.

Challenges and considerations

[00:16:10] It's not all roses of course. There are challenges and considerations that we need to think about. The first one is React support. If you don't use React, slides now for you, but if you do use React, I do want to mention that they do support web components, but they don't support some of the developer ergonomic features that a lot of the other frameworks do. Fortunately the React team has been working on changes for this, and I've heard that in their next release they're going to be including these changes, which is really exciting for us. However, we also know that teams can't just switch the second day the new React version comes out. That's going to take time, especially at a large company. You may not have the resources to do that right away.

[00:16:53] So Lit, which I mentioned before, was the boilerplate code that we use, that library that's built by Google. They've also created a wrapper generator for React, so we now have a React wrapper around our web components and that's built within our pipeline steps, so we don't have to do any type of manual work or do any additional development. Our React consumers can just pull from that part of our repo and it works the same exact way as if you were using a web component, but you get those developer ergonomic features that you wouldn't normally have.

[00:17:27] Next we have server-side rendering. Server-side rendering is supported with web components. These are some new features that came out recently, but there are some changes that you need to think about when building those web components as well as in your application.

[00:17:43] And finally we have resistance to change. With any large change, especially for something as large as the design system, you need to make sure you're making the right call in order to do that, and to convince others it's best to reach out to folks. During that time period when we initially were building out with Angular, React and AEM, we saw that it wasn't working. We decided to look to the industry, figure out what others were doing. We reached out to folks from Adobe, from Shoelace, which Cory LaViska is running that project. It was just adopted, brought in by another company, fantastic work there, and they were able to give us a lot of insight. I encourage you, if you have any questions I'm happy to meet with any of you after the talk, but get some feedback from the industry and then bring it back to your teams. That's how we got everybody on board.

Results and feedback

[00:18:33] And now for the results and feedback. Since we made this pivot it's been about nine months. During that time we have made 36 components and 12 web applications are using the design system. I can say, actually this morning I was looking at my email and I saw that another consumer was actually at it, so we're jumping up to 13 there. And then, of those existing 12, there were four application technologies used and I want to make sure to note those. Some of them were using Angular, others were using React, others were using AEM, but I think the most interesting one was a project that was a more legacy project that we're using JSP still. This technology worked with those JSPs without a ton of additional work. They didn't have to include a whole framework to get it to work for them, they were just able to use the assets that we provided them, which is really exciting for us.

[00:19:28] If those numbers aren't enough, I want to go over a few pieces of feedback. The first one is about one source of truth. This was a React and AEM application developer and they said, centralizing around web technologies reduces the need to learn new component APIs when switching between applications. If you're doing all this context switching anyway, why do we need to introduce a whole other layer of context switching, which is to understand a brand new API when they're going back and forth? This enabled them to work a lot faster and it's a lot cleaner for them because they know where to fix the bugs.

[00:20:02] The next one, and I'm really excited about this one, is prototyping. This was by an A/B tester, and they said that web components make prototyping and A/B testing more efficient as they can be directly imported into web pages without requiring build tools. What their process looked like before was that they had to work with the technology that whatever team was building their application in, to make sure that the component would work on their web page. Well now, since the browser supports the components that are being used, they can drag and drop it right in and it just works. So if we create a button and they want to theme it differently, they can drag and drop that button on the page, they can style it, and they can check to see how well that works with the consumer.

[00:20:45] Next we have shareable patterns. They said, Beacon, the design system, provides technical patterns that can be used in any framework, and this allows us to easily use and apply them in our own application. So now we're seeing that these standards that we're using here and the process that we're putting in place can also now be used across other applications, and we're seeing it in use and it's working well. There are some components out there that don't necessarily make it into the design system. Maybe they're more composite components, maybe they're making calls to a service, but they still should be shared across different parts of the org. Well, that's where these types of patterns come into play, and this individual was saying that that had really helped them out.

[00:21:24] And then finally, theming, one of the things I've been mentioning pretty consistently throughout this talk. Design tokens enable our team to efficiently and reliably adapt existing experiences to a shared design framework. This was an AEM developer working on a somewhat legacy application. They had components that were built several years ago, pre-design system, and they found that by having these design tokens and the CSS variables that were generated, it allowed them to better style their existing componentry while they were onboarding to the new design system with our components.

[00:21:59] All right, some key learnings to mention. With this pattern we now have a modular approach, one that doesn't require build steps after publishing. It's also interoperable, meaning that you can choose a framework, bring it to the table at the application level, and you can use the components in there as well. But most importantly it's sustainable. We can build for today without negatively impacting the future. Thank you, appreciate it.

Q&A

[00:22:29] Host: Thank you so much, Alex. I think in this current climate we're all looking for ways to become more efficient and more effective, and I think design systems are a really great way for teams to really push forward their development and enable teams to move faster. So, questions for Alex. Is there anything up online? Yes, awesome, we have a few questions from the live audience. The first question is from Ruchon Myers [?]. Is there a plan to consolidate the various JS frameworks into a streamlined approach?

[00:23:03] Alex: I think that's an organizational challenge, and that also takes time, but it is something that we at T. Rowe are looking to move towards. But we also want to encourage new ways of working and we don't want to restrict ourselves necessarily to a single framework. I do want to mention that this is a talk not to bash frameworks in general. There are places for all of these technologies, but the best thing to mention is that the use case that we're using these for, it makes sense for a design system. So if teams want to use Vue and there's an actual use case, there's a case for that, then I would encourage them to do it. But we should probably have some more standards around the frameworks within our organization, and I would encourage others to have that as well, even if it's narrowing it down to a subset from what they have today.

[00:23:54] Host: Awesome, all right, thank you. Adam Carrignon [?] asks, how do you handle the tab index and CSS order?

[00:24:04] Alex: Tab index and CSS order. Well, it depends on the component, depends on the feature. We oftentimes are looking for existing ways to handle that. Sometimes it's with JavaScript. We try to use mostly HTML and CSS, but if we have to put maybe some attributes on the HTML elements themselves to make them more accessible, we'll do that to increase the tabbing capability within the component. One example would be like the modal, how do you focus trap within that? So we had to add additional functionality to do that with JavaScript.

[00:24:42] Host: All right, and the last question from the live audience. How do you align with designers on variable naming conventions?

[00:24:52] Alex: That's so tough, naming is so hard. We're doing that now. It originally started, we originally started with the technical approach, and that was because design tokens, to my knowledge, came out more on the tech side than it did the design side. Now that there's a lot more investment in design tokens on the design side, we're looking for ways to sync those up, and the only way to do that is really to make sure that our naming convention is down. So we're trying to make sure that we're providing a bit of context within that CSS variable or the design token naming, but not too much where you would have to memorize a thousand different tokens. It is a super hard topic and I think we're going to see a lot of articles and new ways of working in that space.

[00:25:43] Host: Awesome. Anybody in the crowd? All right, right there. I'm going to pass the ball. What teamwork, I know, I love to see it.

[00:26:01] Audience: Obviously, as we know, design systems take a lot of investment from both design and development. So what was your process for getting your leadership stakeholders to invest in your design system and put in the time and energy it needed to be as successful as it is now?

[00:26:22] Alex: This is an excellent question, I've got an answer for you. Without taking too long with it, the high level is that we started actually with the grassroots approach to our design system. We saw the need, we saw the trends on both design and dev side, and we drove it from there. We actually created the initial version with all of the other developers and designers, just through meetings, like weekly meetings. We were creating new things and making sure that it would work for the developers that we were creating them for. And then over time people started using these things, we were able to show value.

[00:27:01] Alex: With that value we were able to go to the management and say, hey, there's this value, we have about eight teams already using this, so should we now fund it? And we eventually got quite a bit of funding because we were able to show that value, and that spoke louder than, hey, we want to just reuse this thing and we also want to make sure there's consistency. Having those numbers really helped us. That was our route, but it really differs between companies, because if you have management that already knows about this type of system and they're already on board with it, then you have to do a lot less leg work. But now we have the entire organization, from bottom to top, all invested in this, and we have objectives set aside to make sure that people and teams are using these tools and that we're using them properly. That's a bit about how we went about it, but would be happy to talk with you afterward if you're more interested. Thank you.

[00:27:54] Host: Yeah, I'm right up here in the front. Thank you so much. I do love this thing. I know, it's great. You can toss it, but you might hit someone.

[00:28:09] Audience: So the numbers that you shared, of how many components you created, the adoption after your pivot, what size team, both on development and UI design, were you working with to get those numbers?

[00:28:23] Alex: We now have a team of approximately seven developers, six full-time, and several designers that are in London. So we have the developers in the US, designers based in London. That's kind of what we've had for the past, I want to say, year or so, a year, year and a half, all design system dedicated. It took a good bit to get there, but we were able to negotiate how we wanted to fund it and what kind of resources we wanted to build this up. And then it wasn't all at once, by the way. This wasn't like, hey, here's six devs. We started off with an entry level engineer to join the team. He's still with the team, excellent dev, and we actually grew it out that way. So we had more folks come in from our entry level program, we got them trained up on front-end best practices, and they're now building out this system. So we're able to fund it with that approach.

[00:29:27] Host: Awesome, thank you so much. Please give another round of applause.

Speaker

Alex Wilson

Alex Wilson

VP, Senior Design System Engineering Manager

T. Rowe Price