 So yeah, so as mentioned, my name's David Wells. I'm a full stack JavaScript developer based out of San Francisco. We're at a company called Serverless, which, if you guys were here on Tuesday, you might have seen our CEO, Austin, talking about what Serverless is. But previously, before I worked at Serverless, I worked at a company called MuleSoft on the UX UI team. And I want to take a quick second to thank Full Stack Fest for inviting me to talk here. It's awesome to be in Barcelona. It's always great to travel. And the slides for my presentation can be found right there at that tiny link. But cool, so I'm going to start off with a story. The story is about a quest, a quest for the perfect platform user interface. What would be the ideal setup for a larger project? This is something that I feel like a lot of us strive to reach. And it seems like an unattainable goal as things are always changing. And more specifically, when I talk about Platform UI, when you're working with a larger team or you're perhaps working across multiple departments in your organization, how do you build out UI that transcends those boundaries? And this is the number of JavaScript frameworks that were released this previous week, 1,972. There's no shortage of ways to do things. And each one comes with its upsides and downsides. But I'm here to tell the tale basically what I've learned over the past two years building Platform UI and some mistakes to avoid and some best practices to take back into your own companies. So first, imagine in your minds what the perfect setup would be for your UI. Just think about it for a second. What's the perfect back end? What's the perfect front end? What kind of CSS setup would you want? Start imagining that. And I'll tell you mine. So first and foremost, imagine a scenario where your UI is running out of a single code base that's shared across multiple areas of your company, shared across like the marketing site is using it, your blog is using it, your web applications are using it, your mobile apps are using it, and even you're using it inside of legacy applications. And this setup is shared across teams and across platforms. Like I mentioned, mobile desktop web, you name it. So that's like an ideal setup for me. I want it to work everywhere and have one code base to maintain and use. So the other thing would be organized. So it'd be super organized. What if every single layout, icon, font, building block, component, button, link, whatever you use is in one centralized location for all developers to use. And one place where people can find things and freely contribute to that. The other kind of core tenant that I would strive for is like keeping things in sync. So if we have this one single code base to rule them all, like a platform UI, as it were, what if your latest style change could propagate across all of your applications all at once? That would be pretty compelling and a huge problem that companies with more than one application and a larger team face on a pretty regular basis. So just imagine having that kind of platform leverage where deploying code and updates across apps is easy. And even better than that, just imagine a consistent brand experience for your end user. So every single thing that they touch, whether it's the marketing site, the blog, inside of your application, your mobile app, everything is cohesive and just feels like it was put together with care. And then everything, the ideal setup would be like it's also self-contained. So imagine a world where your CSS is completely self-contained and is guaranteed not to cause conflicts with other applications, other third-party CSS libraries. You name it. It's isolated. That sounds pretty compelling to me. And then the last thing is like, how do we actually have a scalable solution that achieves all of these things and that work across the company? So scalable from both a people perspective of, is this code actually maintainable? And from a tech perspective as well, like, does it work everywhere? Will it handle all of our needs? Is it performant, et cetera? And that's basically what we're going to be chatting about today. Basically, Platform UI, building a component-based architecture. And a component-based architecture basically enables all of the things that I told you guys to imagine are possible today with this kind of setup that I'm going to run through. And more specifically today, we're going to be talking about a React component-based architecture, but there's no reason why these kind of ideas and methodologies can't apply to your framework of choice. So let's go ahead and explore this. So it all starts with a design system. So a design system is basically a place where you formalize your user interface, all the different kind of layouts. You have the tonality of how your application is going to work, your brand. A lot of people call them style guides. There's tons of examples out there on the web, but it just makes things easier for both internal and external people to consume and build things with. So there's a couple of different examples. So this is a really good one out of Salesforce called the Lightning Design System. I highly recommend checking that out. They did a really, really good job basically baking in all the different rules for how to do different layouts for settings pages, for list pages, for feed pages, et cetera, how all the different variations of buttons are managed, and stuff like that. It's basically how to do everything with their UI framework. It's super handy, I would imagine, for everyone inside of Salesforce and outside building apps for the Salesforce platform. But what we're going to be talking about today is the component library that I built at MuleSoft, and you can see it at ux.mulesoft.com. And basically, it's, again, the one-stop shop where you can go and see all the different components that are consumable, all the documentation, all the different icons, all the different colors, all the variables and mix-ins available to developers, and some actual layout demos, and kind of standards around that. So I'm gonna skip the live demo till the end. But yeah, so what lives in this style guide? So documentation, like I mentioned, so this is both documentation that's written by the team, but also documentation that lives directly in your code. So when you're building React components, if you're using PropTypes, you can basically automatically generate the documentation for your component library so you don't have to maintain text in a different place whenever you make a change in your code. That's automatically reflected in basically your living style guide. The other thing that I put in here is a live code playground where basically you can interact with the components, change the props, see how they act, and mix and match them together, and we'll see that in the live demo. And then also, what's extremely important is usage examples. So how do you actually use this component with some dummy data? So you're basically, you're almost writing the code for your team so they can kind of get off building their specific use case quickly. And then also platform guidelines, like I mentioned, like how to show warning text, when to use certain types of buttons, et cetera. So you have a very consistent feel. So when your user is moving around to maybe different applications, the experience feels the same. And just a little bit of context around this, MuleSoft has around eight different products that were kind of all built in silos over the past couple of years. And the experience wasn't as cohesive as we wanted it to be. So that's kind of the idea behind why we wanted to do this. Yeah, cool, but how? So this is all like pie in the sky, like yeah, this sounds good, but how do we actually go about doing this? And it's pretty straightforward. We're gonna run through these five things. We might not run through profit maybe later, I don't know, we'll see. But yeah, so basically, we need to break things down. We need to figure out how we're gonna actually handle like our CSS, like I mentioned, how we're gonna handle all the global assets to be easily consumable, and then how to actually package them and distribute them out to different teams, or to the public if you decide to maybe open source your component library and profit. So cool, so this is an example of like UI, this is a demo on the ux.mulestop.com, but basically start by breaking down a particular view of your application and start thinking about things as components. Everything on this screen is a component. So every single tiny little piece, like the radio buttons, the chart, the icons, the labels, the drop downs, et cetera, like each tiny piece can be broken out into a separate component and reused across multiple areas of your application. So basically you start thinking about your UI in such a way where it's like, how can I build this design that the designer has given me into something with the maximum amount of code reuse? And that's really what like React, the kind of core philosophy around React is like, how can you componentize things and make the code easily easy to reuse? And then after that you basically have like, once you have all the little tiny pieces, the individual components, how do you compose those together to create maybe more complex components? And here we have an example of like, so the nav bar is a component, the detail pane is a component, the menus a component and like the table, is they're all made up of smaller pieces but for the consuming developer, they're just pulling in that one larger piece. And this kind of riffs off of a concept called atomic design by a guy named Brad Frost. I highly recommend checking out his post on this where basically he says like, okay, take atoms, like little tiny pieces of your application, then compose them into molecules, then into bigger organisms, then into page templates and then finally like full actual done pages. This inspired me to kind of follow this pattern. We don't follow it exactly like that but very similarly. So here's an example. So here are all like three tiny atoms or components if you will, a label, an input and a button. And basically you can compose those together now to create a, let's say a search box or a form input or a modal or let's say it's a marketing copy with a button thingy on the blog or whatever. So there's a lot of different ways that you can use these three components and compose them together to create basically composed components to use throughout your application. Cool, so just to stress again, everything is a component, I'm a component, you're a component, we're all components. Okay, that's the moral of the story. Cool, so what does it actually look like? What does like a component look like in code? This is the anatomy in which we build components. We're basically like all of our components live in a components repository. Every component gets its own folder. Every component has like a component name.js so like button.js, that's where the actual source code of the component lives. The styles live in there. The tests live in there in that same folder and then we have an index file for easy importing and exporting and then we also have examples. So uses examples, so that examples folder is actually what automatically generates the documentation and live code examples on the site that I'm gonna show you. Cool, so our approach at serverals is slightly different take on atomic design where we have the low level components. Those compose into what I'm calling fragments right now I'm trying to find a good name. That's what I came up with. Those fragments compose into layouts and those layouts compose into pages. So this is serverless.com. It's built with our component library. So this is our front end marketing site. It's a statically built website completely with React and then we push that up to a CDN and yeah. So we can use the components that we're actually using in our applications that we're building and in our marketing site and on our blog, et cetera. So if we did ever make a change to let's say that the button design that would reflect throughout the platform, not just in our app and then we would have to go update, let's say like WordPress or whatever we're actually, if we had that as our marketing site. And under the hood, the tool it's using is called Phenomic which is a static site generator that uses React. Super awesome, there's a link here in the slide to check it out. Yeah, so cool. So here's the obligatory Peter Griffin CSS slide that by law you must put in every presentation where you mentioned CSS. And we're gonna talk about handling styles in your component library. So, yeah. So basically there's some challenges with CSS, right? So we've all faced it like how do you handle class name collisions? How do you handle if you're using like a third party CSS library like Bootstrap? How do like if we wanna use these components inside of a legacy application, how do we make sure the styles don't conflict? Like what we had to do at MuleSoft is there were some green field projects that just were built with the components but there were also a lot of legacy applications that were built in Angular 1 with Bootstrap and a whole bunch of other stuff where we had to make the components basically live inside of that application. So we needed to make sure that we're not messing with their stuff and they're not messing with our stuff which is quite a challenge, but it is actually pretty easily doable. Cool. And this is a real quote from our favorite presidential nominee. Name space collisions are a threat and we must beat that threat. If you really want your components to be standalone, we need to solve that. So how do we do that? So basically we use a technology called Post-CSS and CSS modules and this works with Webpack if you're familiar with Webpack. I have an entire like hour long presentation on exactly how to do CSS with React. The links are right there and it goes through like all the different variations of how you can do styling. I'm just focusing right now on like my favorite and the one that works best in this platform UI situation which is Post-CSS and CSS modules. But what Post-CSS is is you can think about it like it's babble for CSS. It'll turn your CSS into an abstract syntax tree and then you can manipulate that. It's exactly the same as well not exactly but very similar to SAS and less except just a little bit I think more powerful in my opinion and you can do everything that you can do with SAS and less with Post-CSS. Cool. So what does it look like? So this is a React component. At the top I'm importing the styles from the CSS file and it's just normal CSS. But what's happening here is that styles that's being imported is actually so it's being turned into an object with keys on it and those keys are basically localized class names. Now your CSS names that you're writing normal CSS so wrapper and like the class of button get turned into this localized class when it actually renders to the page and that's either if you're rendering on runtime or if you're rendering on the server this is what it looks like. So and that is customizable by the way. This is that's a long like name. You can just for production you would customize that to just be the hash at the end. So if you look at like Gmail source code or anything like that you'll notice like they have crazy class names that are hash numbers. This is how you achieve something like that. The other thing that you'd want to do is with post CSS there is a plugin called I believe it's called post CSS initial where basically it turns on a future CSS for spec for you which basically is all colon initial and what that'll do is it will reset all inherited properties. All CSS properties that can be inherited from a parent and reset them to the browser defaults. So when you add that to your CSS just all colon initial when post CSS transpiles your CSS it will like basically polyfill that for the browser so it'll reset that. So now you have like a completely isolated component based off this unique class name which is awesome and something that we couldn't really do before very easily. The other thing that you could do with like post CSS and CSS modules is like use the CSS for spec today. You can do like A11y linting for accessibility. Yeah and you can polyfill flexbox back to IE8 if that's something you have to support. And I feel sorry for you if you do. But yeah so yeah so many many many many other things you can do with post CSS and CSS modules not gonna go through all of this. See the go check out the other talk that I did at the React Meetup in San Francisco. Cool so do you really need this? If you answer yes to any of these questions then yeah if you're working on a team like you could implement BIM style writing your CSS classes but we're humans and humans make mistakes. This makes it so like you cannot make mistakes. The class name is localized for you by a machine based off like a random hash based off the file name so it's completely unique won't run into collisions. Are you including any third party CSS so like do you have to use Foundation or Bootstrap or any other library that conflict with your stuff? Yeah this will kind of make your life a lot easier. Are you running in a third party environment? The answer to this for everyone is yes because the browser is a third party environment meaning anybody could install any kind of browser extension and theme your app however they want. If you wanna stop that you can do this. And then yeah so and do you want your styles to look right no matter what? The answer to that should be yes. Cool so that is kind of post CSS in a nutshell. Really really like transforms how you can write your CSS normal regular CSS and then automatically transpile that into something that will get rid of global namespaces and fix the main problems with CSS. It also allows you like some there are some use cases where you do need global CSS and it gives you an escape hatch to do that. Like an example would be for like let's say a modal pops open and you wanna add a class to the body that does something like you can do stuff like that with it. Cool so how do you handle global assets? So global assets meaning variables, mixins and icons. So variables and mixins. No longer do you need to write your variables and mixins in CSS. You can just do it in JavaScript why not? JavaScript is eating the world and it's far more powerful than writing like let's say a mix in function. You're writing if you're writing a mix in function in SAS you're kind of using this weird syntax that's not really supposed to do this thing. But if you write it in JavaScript you're just writing a JavaScript function that returns something. You have the full access to the NPM ecosystem to do whatever you want. This is how you enable this with post CSS. This is basically you require two plugins. So it's very similar to Babel. You would include what you actually want to do in the transpilation step. But here I'm just saying, okay, grab my mixins file and grab my variables file and then make that globally available to all of my CSS. And what that looks like, this might be a little hard to see. So this is the variables.js file just as an example where I'm just, it's just an object. So I'm defining my various break points. I'm defining platform-wide Z indexes to use everywhere, my colors, et cetera. And then on the right-hand side there we have our mixins, which a mixin is pretty much just like multiple values at once. And interestingly down at the bottom it's a function which you can pass in any value you want or use an NPM package to like calculate a different color or something. Like you can do whatever you want. And the usage in the CSS is just like at, so I'm using a mixin at denpro, use that font, and then a variable there. So very similar to lesson sass, but yeah. And then what's cool about this, because it's written in JavaScript, is I can also use this inside of my components. So now if I have, let's say, state-based, like I wanna add a red text to a button because something bad happened, I can import my brand color red from my variables file because it's just a JavaScript object and use that where I want to. So cool, running short on time so I'm gonna speed it up a little bit. So icons, so if you're doing icons, font icons are kind of going the way of the dinosaur. They're not as flexible as SVG icons. SVGs are also typically lighter weight and more flexible than font icons. For example, SVGs, I mean, it's markup that you can style individual lines and strokes, whereas font icons are just a single color that you can apply different colors to. But here you can see we have a ton of different SVG icons that are multicolored and we can change those individual colors with CSS whenever we want or do cool animations and yada, yada, yada. But the way that that works is designers make the SVGs. There's a build script that runs through all the SVGs, runs it through Webpack, bundles it with a Webpack plugin called Webpack SVG Store. It will optimize everything and create a sprite. And then you have an icon sprite of an SVG icon sprite that gets injected into the DOM. And then again, you can profit. And the way that that works is with the SVG use tag. So if you have a SVG sprite on the page, it's hidden, nobody can see it. But anywhere you use SVG and then the use tag and the ID of the corresponding icon in the sprite, it'll just render your icon right there, which is super handy. Cool. And so how can I build this? This is all super cool. How can I build this stuff? So at MuleSoft, it was a custom solution that I built. But we're using some open source things and maybe one day the library will be actually open sourced. I think they're working on that. But here are some other resources for you guys. So there's a project called Car Blanche where basically it will kind of build out that component library for you. You give it a path, it's a webpack plugin, and you give it a path to where your components live. It will then generate this kind of UI for you. And it'll also do some cool stuff, like build out your examples and really stress tests. Like, oh, what happens when all these weird properties are passed into this component? There's also a React Storybook, which is very similar to this, where it's kind of like writing tests though, where you're writing examples for your components. React Doctrine from the React core team, super handy. You could basically pass a directory of React components, as long as those React components have prop types and comments above the prop types. They will automatically generate, basically give you an object back for you to do whatever you want with. That's actually what we're using under the hood with our solution. Or you could roll your own. Again, with React Doctrine, it's a command line tool, but you can basically give it a path. It'll spit back all the data about that component, and then you can just render out whatever you want so you can get creative there. Our Component Library uses these two links at the bottom here, the React Component Illustrator, and its corresponding Webpack plugin. This does the same thing as React Doctrine, it's using it under the hood, but it also will grab those example files that I showed in that Component Anatomy, and it will take that example source code and also make that available to me in the user interface for the Component Library. So people can see that code and interact with it. So if you're interested in that, check out those two links. Cool. This is a last minute, really awful diagram that I put in here. Or basically, this is kind of the idea. So you have all these consumers, you have one single source of truth, your Component Library, where your components live in there, your mixins live in there, your variables live in there, all the font stuff, your typography rules, et cetera. And then when you make an update, you can basically propagate that out throughout your applications. It's important to use semantic versioning. So if there are breaking changes, you want to make sure that those don't actually get passed through your CI-CD system. But yeah, cool. And just to get you guys started, there's a bunch of open source component libraries out there. Many of them have this kind of like living style guide, which you could fork and kind of do whatever with. But you don't need to start from scratch if you're working with React. There's tons of stuff to leverage or just to see how specific components are built. Cool. So let's talk about distribution. So how do I actually get this out to my team? How can they actually consume it? And that's just very simply with Webpack and with MPM. There's a couple important things to note though with this. So you want to, with your Component Library, you want to build each component separately. You don't want to build this massive index file or this output to this lib file because then if, let's say a consuming application is only using two components or three components or maybe four, they would, in their bundle, they would have everything. And it's going to be rather large until tree shaking is like relatively used everywhere. It's going to be a problem and the bundle size is going to grow tremendously. So what you want to do is build each individual component separately and give it its own entry point basically, where then the consumer would just import button from at your Component Library and then the built output. And what this looks like, because you're building each thing into like a flat directory structure, what that means is like now you can externalize all of the components that each component is using. And like basically, so let's, for this example, the button component, it also uses the icon component. It also uses the tooltip component. And if you weren't building these separately and externalizing, which is a webpack feature, externalizing those, button would have the entire source code for icon and it would have the entire source code for tooltip and it's like built output. And then the consumer app could also be using other things that use tooltip and there's basically code duplication that you want to avoid. What we also did to keep the bundle sizes down is we also externalized the CSS. So this requires that the consumer also uses post-CSS but it's for our team at MuleSoft so that's fine and everyone can do that. And this also means that when the CSS, when the actual application is built, it'll only use the CSS that the application is using it won't use other stuff. And you can also pipe that down to the browser in a CSS file rather than in the JavaScript bundle. And browsers can request multiple files concurrently so this is kind of a performance optimization. Cool so and then the other kind of like core piece of this especially if a lot of people are consuming your components is like how do you actually know that? Like what components are being used where? Like it's very hard to keep track of that stuff manually so this code you could actually probably just grab and tweak a little bit but basically this will, every time webpack builds it will parse through. Webpack gives you the entire file structure of your application, all the things that are being imported so you can basically just check and see, okay what components is this consuming application actually using and then report that back? So we set this up at MuleSoft to actually ping a Lambda function with a serverless framework, shameless plug to store that so I actually know what version of the application it was, what components that they're consuming and that basically helps inform the team of okay we're making this change to component XYZ who's actually consuming it? Okay I can see that there's these three applications consuming it, cool when we make this change let's double check those three applications that we didn't do something bad so it's important to have that kind of visibility in there. Cool and then some lessons learned. So you want to be like very vigilant with your component APIs, it's super, super easy to say like okay let's add all the properties you need to do this, you have a use case for this, you have a use case for this, your props start to grow out of control and it's really, really hard to deprecate props. Yeah so basically you want to be vigilant and make sure that use higher order components basically wrapping the component in another component if there's like some one off use cases that you need don't just add more and more props. Yeah don't add things so you have use cases for them this was a conversation all the time of like hey what about this future use case that we don't have yet that we may never have? We yeah you want to avoid stuff like that. Name things well and agree on a standard so I have a blog post prop type naming conventions so we try to mirror the DOM as close as possible we don't want to reinvent API like things if it's really just mapping down to a DOM primitive use like really good naming conventions for props like for example if it's a Boolean property use is filled or is open or has value instead of just value or whatever or filled. Yeah and avoid unnecessary abstractions. Set up linting first that's something that I didn't do which was stupid and I had to go back and like update an entire code base later which is painful. Test server side render ability early and often this is something that we didn't do in the beginning and I had to go back and like retrofit a lot of code if you are gonna be rendering on the server or if you want a static website like I showed you wanna make sure that you basically aren't doing any document or window calls in your components but yeah cool. So yeah so let me actually I'm gonna show you guys the component library and then I'll wrap up with some final thoughts. So this is the MuleSoft component library. We have basically all this stuff automatically generated from the source code. There we go. So this is it. Okay no this is gonna be hard to demo now. Okay so basically these are all like working components. You can actually see the usage here of like okay here is my component. Here's all the props that I'm giving it. This documentation the prop types and the comments are automatically generated from the code. This is a live code editor so I can change this to danger let's say and you could see this is now a danger button. But yeah so it's basically like this is exactly how you use this component in your application. I wrote the code for you so you don't have to. And what this like allows is for like really really really quick prototyping and really really fast basically iterations on products. Likewise we have some demos. So this is kind of what I showed before. And also I can't go back. So we also have our typography all the colors which is being automatically generated from that JavaScript file and just looping over that printing amount and all of our icons. And these are all like basically SVG use tags. Let me show you guys what that looks like. So here's our SVG and here is the use tag that's just referencing the sprite that's down in the bottom of the page. So this means like you don't want to inline like icons everywhere especially if you're using icons in a table or whatever it's going to make your DOM super heavy. So you want to keep those things kind of down to a minimum. But yeah, so that is the live demo. Well, so some final thoughts. So with this setup you can basically like achieve like a faster development velocity. If everyone's consuming the same things and contributing back to the same code base you can do things a lot faster. That's not to say that everything needs to like every component needs to live in the component library. We did have some use cases where like project XYZ had some custom things that it needed. So those components just lived in their repository. And then sometimes they actually were like, oh, we actually need that in other things. Let's move that into the component library and use it elsewhere. But yeah, individuals can work on these like isolated components without worrying about breaking things. The main thing for me is like having a multi-platform component library. So again, targeting mobile browser and desktop. And having it like basically on all of our assets. So I don't have to maintain three different sets of CSS. I just maintain my component library. I can use that again on my marketing site, on my blog, on any demo apps inside of the application and you name it. Yeah. And you can render this stuff statically. So server-side rendering for better user experience and indexability. And yeah, and if you choose the static path, so this is again using something like Phenomic, you can render your, basically it's doing server-side rendering like in your CI system. And then it's deploying that out through a CDN. So you basically have like raw scale like out of the box if your application isn't that dynamic, which is what we're doing a lot of. So like no matter how much traffic goes to like our site or whatever, it's on a CDN. So it doesn't really matter. We're not rendering that over and over again, only once that build. Yeah, so that in my opinion is like the future stack. And I hope that was informative. And yeah, let me know if you guys have any questions on Twitter. I'm at David Wells. Yeah, and these are my favorite pieces of technology right now. Cool. Thank you.