 Take it away when you're ready. Cool. Thanks, Brian. So yeah, my name's Jack Taranto. I'm a front-end developer at Previous Next. I've just clocked over 10 years working for Previous Next. Thanks, Owen, for the bottle of scotch. So I must be doing something right. So yeah, thanks, Heaps, for coming. This is building your design system. So I wanted to give this a bit of a personal touch at the start and give you guys a bit of background about me. These are my two kids, Sophia and Zuzanna. That's them eating strawberries. They like strawberries. They eat strawberries quite a lot. We live here. This is a tiny little town called Talong. I think there's like 800 people that live there, or less even. It's in the southern highlands in New South Wales. And this is what it looks like. It's a super beautiful picturesque little place we've got. That's my office there. We got snow a couple of months ago. It's super dry at the moment, but that's it. So yeah, first a little bit of history. At PNX, we've been using Starguides for probably the last six years or so. So Drupal theming has a long-time reputation for being tricky and frustrating. Starguide-driven development allowed us to abstract the bulk of our front-end workflow out into a completely separate stack. So that was a true revelation when we started out doing that. It allowed us to bring on front-end devs that aren't Drupal developers without throwing them in the deep end that's Drupal theming. So once a Starguide is built for a project, it then goes on to become a documentation resource for a client. It also allows back-end developers to continue building out a site with a library of components. For every major site we've launched in that past time, there's been a complete Starguide to accompany it. So at what point does a Starguide become a design system? It's important to see the Starguide as a development tool. It includes front-end code with some limited documentation on how to use that code. A design system is the next stage. It's the evolution of a Starguide. I see it as our development practices cementing to something far more tangible. It's a source of truth, and it encompasses everything digital and organization might want to produce. It's more than a development tool. Both a design system and a Starguide are, at their core, a documentation resource for a set of components. But a design system is designed from the ground up. It's not necessarily something built with standard tools. To be successful, it needs to be treated as a project in its own right. So like a Starguide, it's going to include a list of components, maybe less like a Starguide. It's going to include detailed guidelines and instructions on how to use those components from a development perspective, but additionally from a design perspective. It's going to include organization-wide preferences like color, typography, and white space with detailed instructions on how they should be used. At its core, it's just a website, though. So let's take a quick look at some examples. And if you're interested in design systems, definitely check out Rich's talk, which is next up, I think. So yeah, Brexit's proving pretty tough for the UK to crack at the moment. But they've been, this design system's been the poster child for a long time. This is the AUGov design system. It's really matured, and they're using a lot of the tools we'll be looking at in a minute. Atlassian, and yeah, Google Material Design. It's been around for a while. I think we're still waiting for Google to adopt it. So yeah, this is the core principle of a design system. The goal is to get visual designers, content designers, developers, grum masters, CEOs, and ministers all on the same page. Done successfully, it will establish this language in a long-lasting form that can be used by everyone in your organization. So what goes into one, a lot of work, firstly. It's not something that comes together in a few sprints. It's gonna take a lot of consultation. It's gonna take one or a few designers some time to create and design and test the work. Then you'll need some savvy front-end developers to put that code, put it into code in a way that's clear and makes sense for less front-end savvy developers to use. But purely from a practical perspective, what should it encompass? So colors, they're pretty important. Where a design system would differ from a style guide is the reasoning of each color's explained. Yeah, there should be context around the how and why. Typography, words, they're important too. So again, we've got context around type. Why is it being used? How do you use it? Spacing and white space, having to find rules and reasoning behind spacing makes so many common problems go away. So the intersection of components is just as important as the components themselves. Branding logo is probably important. These would apply for an organization-specific design system. Then we have the components. It's a pretty ambiguous term. We'd call a component any UI element. You should include any component that's gonna get used more than once. If you're building something that's totally unique or specific, then maybe it shouldn't end up in the design system. So layout, a grid system. This is really important, fully fleshed out. They're pretty useful. I find them particularly fun to build as well. It helps satisfy my OCD syndrome. So, yeah, what shouldn't it include? I think that comes down to the scope of what your organization does. I'd say at a common level, any one-off items that are unlikely to be reused can be spun off into their own code bases. Yeah, ask yourself the question, is this useful for someone else? Does this help communicate something that's important? If the answer is yes, then bring it in and document it. So a design system is a product, and it should be treated like one. It should have a backlog. It needs a multi-discipline team. UX designers, visual designers, developers. It's gonna need a significant investment to pull off in a polished fashion. But the value of a design system can't really be overstated. The amount of time, effort, and confusion you'll save is pretty impossible to quantify, particularly for large organizations. So, yeah, I'll say first, there's no right or wrong way. Instead, there's a few pieces of the puzzle. You wanna make sure you've got covered. So let's come back to the idea of a design system as a communication tool. What exactly are we trying to communicate? So there's three things, primarily. The design itself, visually, what things look like. And we looked at some design examples earlier. Then we have the code, the HTML, the CSS, the JavaScript, the React, and everything else. And yeah, probably the most important piece, the documentation. The guidelines, the instructions on how to use the contents of the design system. So, yeah, add these three up, and ideally, you get a website. That's the finished product, essentially. But basically, we want a website to contain all the info we've talked about. So, yeah, how do we build a website for a design system? We'll just take a quick look at some of the tooling. Pinex standardized on KSS node quite a while ago. Basically, every style guide or design system we've built uses KSS node. So what's so good about it? Documentation for code and components is written inside CSS using a really simple syntax. This is great for developers, both writing and reading the documentation. There's Drupal integration built right in, and using twig in KSS means you can have the, the exact same templates driving your design system and the Drupal site. It's super customizable. You can roll your own templates and customize everything that goes into it. A couple of cons, it's pretty rigid structure-wise. So there's one template file which drives the whole website. It works best for a simple document structure. I think the complex design systems we looked at before wouldn't have been built with KSS. So all the content lives in code. So that makes it very difficult to content manage. Unless you understand code, you can't really contribute to the documentation. And yeah, you probably wouldn't use the out-of-the-box themes. So you'll have to factor in additional effort to build one from scratch. So Storybook has emerged as a really solid replacement for KSS node. It's way more modern in its tooling. It's got a lot of really powerful features built in. Things like viewport sizing, color contrast, accessibility checking, grid overlays. It's got a docs plug-in, which gives you documentation written in mark-down, which makes it easier to content manage and contribute to. Yeah, the docs pages look great. They're interactive, customizable. And it's got a lot of really powerful features that create their interactive, customizable. And yeah, there are plug-ins basically for every front-end technology in use, so you can really use anything with it. And yeah, on the other hand, it's layout and design is really set in stone. You can theme it to a degree, but I think what you're looking at with Storybook is a defined tool. It's not really like a customized experience. One Storybook site's gonna look very similar to any other. And it really is a tool for developers. I think anyone can use it. It's intuitive, but it's powerful, and with that comes a pretty complex interface. It'll allow developers and designers to communicate, but not with the ease that some of the examples we looked at earlier. So, yeah, KSS and Storybook are both fantastic options to spin up a developer-friendly design system in record time, but those examples we looked at before, they're all custom builds. There isn't really a tool that's gonna pull all of that together for you. So my advice is, providing you've got the motivation, time, and budget, build something from scratch. So yeah, what would that look like? So this is like my wish list for a custom design system build. The whole thing's powered by a static site generator, so we don't wanna code 100 pages by hand. There's tons of options with static site generators, so which one you choose will kind of depend on what you're doing with your front-end stack internally, so I won't go into specific options. Documentation, I think they should be written in Markdown. It's gonna make it somewhat easy to contribute to. You could use Drupal as a content repository, and I'm sure some of the larger design systems do that, but I think there's something to be said for keeping things lean and skilling up your team, so really like anyone should be able to contribute to your docs by editing Markdown files and pushing up pull requests. So yeah, you'll need to demo your components, and the static site generator can help there too. You can build pages with templates that include component markup for examples. You can use a syntax highlighter with some JavaScript to spin your component markup out into code examples. Yeah, you could even get fancy and involve something like code pen as well to bring them both together. And yeah, taking a step back, the overall design of the website should be based on the design system itself, so you'll have like a wealth of components and styles to draw from, so you just combine them all together into a clear design and should save some design work. So yeah, now that we've built the design system website and we've included all our documentation, what about the code that goes into it and how do we help others actually use it? So most design systems will feature a CSS and a JavaScript bundle for developers to include in their project. Combine that with the markup examples in the design system and developers can build out components for themselves. Beyond that simple workflow, the type of code will depend entirely on your organization's tooling. You might be focused heavily on React, so it would certainly make sense that your design system includes React components. However, I'd argue that the most successful design systems don't dictate a technology, a specific technology choice using vanilla CSS and JavaScript means that anyone can take what you've built and use it inside any front-end. Yeah, I think that's the beauty of getting back to the basics and speaking the language of the browser instead of some arbitrary framework. So you can also provide options. So it's possible to support multiple CSS workflows by providing SAS, post-CSS, and vanilla CSS import options. So here's an exit from the Service New South Wales star guide. The accordion CSS gets installed with the MPM command at the top. We then provide the four different options for usage. So post-CSS is the preferred option. It's what we've used to build this star guide. The post-CSS ecosystem of plugins lets us use modern CSS features that haven't made their way into all browsers yet, things like CSS variables and nesting, and it transpiles them into a CSS syntax that is understood by all browsers. Then we have the SAS import through the use of eyeglass. So eyeglass is like a loader for SAS, and it gives it compatibility with MPM. And finally, we have the two options for vanilla CSS, the at import and the link tag. So all four options are valid. They provide a similar experience, and the same CSS ends up in the browser. We could probably go one step further and add a fifth option that would show you how to bring that CSS into a JavaScript app. So using MPM to distribute our packages, can you guys see that at all? Yes, it's way out, hey. Didn't run the color contrast, check on that. So yeah, using MPM is what gives us this flexibility. So here's part of the package.json file for the accordion. So yeah, if you can see that, there is a style property, and it's the original post CSS file. So there's a plugin for post CSS called post CSS import, and it allows an at import that uses the name of the MPM package to directly pull in this file. And moving down, this is the eyeglass section. So that's what provides the SAS import. The name specified here allows an at import to pull in this package. And then yeah, we've got the script section. So this is where I'm running the post CSS command. It spits out a vanilla CSS file into a disk directory, and that's the file that gets used for the SAS import and the vanilla imports. So yeah, an accordion wouldn't be much good without any JavaScript. So for that vanilla JavaScript is the obvious choice. It can be used in any browser and inside any JavaScript framework. It's just pure JavaScript after all. So this example provides two options, the ES6 import and the trusty script tag. So once the required JS has been included, there's a one line example at the bottom there on how to initialize it. So this is the relevant section of the package, Jason, for the JavaScript. That is the main property. So it's what populates the ES6 import. And for that, we're using the disked version of the JavaScript. The disked version is transpiled using rollup and Babel. So there's a CLI command there in the script section. And yeah, building JS like that is what gives you the best compatibility. So NPM really is the ideal way to distribute any front-end libraries. It's likely that your front-end will depend on other NPM packages. So why not just tap into the ecosystem when you come to distribute your code? And there's some pretty big benefits. This is the big one. So yeah, it can't really be understated how important version control is. And it's important for two main reasons. Firstly, for consumers of your design system, being able to pin to a particular version will give them confidence that nothing's gonna break on them. So the app that they've built will continue to work as is until they step in and manually upgrade something. NPM will keep all your past versions of any package as well too. So if they need to roll back, if something's not working as expected, they can. And that surety is also what allows us as developers to change and improve things as we need to. We don't have to worry about breaking anything because our users will have their own test places and test processes in place and they can update things as they need to. So it's extremely liberating to be able to roll out a new major version of something without worrying about backwards compatibility knowing that your users can upgrade in their own time. So just a little primer on semantic versioning of Semver which underpins NPM. So yeah, a developer of any publicly available package, it's super important to be across these three numbers when you release code. So that's the patch version. You can update to a patch version with confidence that nothing's going to break. This is where bug fixes will be added and you pin to the patch version by using the tilled character. This is the minor version. So again, you can update to a minor version with confidence that nothing's gonna break. You'll get new features here and you'll probably get some warnings about deprecations too. However, all your existing code will continue working and you can pin to minor versions by using the carrot character. And yeah, this is the major version. So major version changes mean breaking changes. You won't want NPM to automatically update to a major version as that's where deprecated code is removed and new breaking features are added. And to update to a major version, you'll have to scale release notes and potentially rewrite a lot of your code. So there's a couple of downsides with NPM. I guess the most notable is the main NPM registry. NPM.js.org is public when, for lots of reasons, you might want to keep your code private. I'd probably argue against that though. So firstly, your front-end code is all public anyway. When someone visits your website, it's really easy just to pull down all the front-end assets. Secondly, NPM will only publish what you tell it to. So it's possible to keep your secret source secret by only publishing compiled and minified assets. So only include the source codes when you publish if you want to. So yeah, using the public NPM.js.org registry is by far the easiest option. It's got the lowest barrier of entry for developers coming onto your design system. Yeah, there is the option of private packages as well through an NPM.js.org account or a private NPM registry hosted through GitLab. However, yeah, these options are just a little bit more complex and costly certainly and they will limit your flexibility somewhat. So yeah, how do we distribute with NPM? Your design system is likely to include quite a few different components, some of which will be integral to every user, like typography and colors, others like the accordion might be used less so. So instead of bundling everything up together and insisting that consumers of your design system include a huge asset bundle, it makes sense to split components out into their own NPM packages. And the tool to do that is called learner. So learner works with NPM to help you keep your entire code base inside a single repository and push out individual components into their own NPM packages. That's what's called a mono repository. It includes tools to manage dependencies, version control and to publish packages. So yeah, this is what a mono repository looks like. This is the root directory. It includes all the repo wide things like post CSS and roll up config, stuff that's gonna be used by each package. It's got its own package.json and you can include global dependencies for your project here. Inside the packages directory, these are all the directories that learner will publish. And yeah, inside a package, we've got the source code for each individual package. So the source code for this NPM package is going to be more than just JavaScript. There might be a common misconception with NPM. It's not just for JavaScript. You can distribute any code with NPM and eyeglass and post CSS import are the two tools we looked at to enable CSS integration with NPM. So yeah, we can have tests for each package can live here as well. So in this package, we're using Nightwatch to run functional tests on the accordion as well as acts, which runs the automated accessibility tests. They test for things like color contrast and ARIA roles and attributes. We've got the changelog markdown file. It's important to include that as well. So there's an easy way to automate the maintenance of this file, which I'll go into in a minute. And the read me should include instructions on how to install and use the package and that's file gets featured on the packages homepage on npmjs.org. And finally the package.json file, which we looked at earlier on. This configures the package on the NPM registry. It also contains package specific build steps, which learner will run before the package is published. So yeah, learner itself is configured with a JSON file, which you can't read. We specify the version at the top. So learners got its own versioning as well. So additionally, we can point it to a directory of packages and it has versioning options. So that's, I'm using the independent versioning option. That's what I'd recommend for a design system. It allows each package to have its own version and you can push out changes to one package without pushing out changes to your whole monorepository. And the last couple of options are some pro tips. So yeah, so learners got, this is the command section. So we can specify arguments here, which learner will run, they'll get passed through automatically when you run learner commands. So there's a command called bootstrap and it's what installs dependencies for each package. So I'm using the hoist option there. This will hoist dependencies from the monorepository's root. So yeah, these CLI commands are used to build each package on publish. We've got like Babel and Webpack and Post-CSS. Each one's probably got like a dependency tree of several hundred dependencies. So hoisting will just sim link the binaries up into each package. So you can run those build commands in the package directories and that will save you doubling up on, thousands of dependencies in your monorepository. And yeah, that last line there tells learner to use conventional commits. So these will help learner version packages for you automatically, as well as generate a change log in each package. So conventional commits is a detailed specification to help machines understand your commit messages. Here's a quick breakdown of what one looks like. So this is the type. There's a list of things you can do there. The fixed type tells learner to bump the patch version number and you can use the feet type to bump the minor version number. And you can also add an exclamation mark before the colon and that will tell learner it's a breaking change and that will bump the major version number. Then we've got the scope there. So that's really like an arbitrary description of some component inside the package. Here it concerns the print styles. And after a colon and a space, we have the summarized commit message. So you can include a bigger message as well after a line break and this is what gets added to the change log. So yeah, the, oops, sorry, the final piece of the puzzle is to add these two dependencies and this piece of config to your mono repositories package.json. Commit as in, which you can probably barely see but it's a dependency which gives you an interactive wizard. So when you're committing, you can go through a wizard and just list what everything is. You can enter all your messages in and it will write the structured message for you. And there's another dependency there called CZ conventional change log and it will write the change logs for you based on your commit messages. So all you need to do is just run this one command, learn a publish, and it will, providing your commit messages are written to spec, it will version the packages for you and only things that have changed. It will output an updated change log. It will run any build steps that you have in each individual package and it also publishes your package to the NPM registry. So yeah, let's pull it all together and see what a finished product looks like. We've got the design system website. It can be produced using KSS node storybook or if budget allows a custom static site generator. Documentation should be extensive and ideally written in markdown and committed to the code base. And the design of the website can use existing components from the design system combined with a few bespoke elements to make a unique product. And yeah, code distribution should be handled with NPM, ideally via the public registry. Components in the design system should be split out logically into their own packages using learner and conventional commits are used to easily add semantic versioning to all your packages. Thanks, guys. I think we've got a bit of time for some questions. So far away. Thanks for that. So am I understand this correctly? Using the same design system for all your client websites? We're working on one at the moment called Mixtape which is sort of, we built two sites with it now, I think. Yeah, I think we've still got quite a lot to go on it to kind of expand it. But that's kind of the dream for us, I think. We've got this shared language and Rich is gonna go into this in his talk as well. Yeah, so we've got this shared language now that we're able to use for client sites, basically. Yeah. Thanks. Have you looked at the Storybook MDX format? It's a recent addition to Storybook. Yeah, I'm not, like I'm not a huge Storybook expert, really, I haven't dealt into it too much. Yeah, I did a bit of discovery on it, really just for the talk. And yeah, we're kind of probably evaluate it fully and see if we're gonna use it in the near future, I think. But yeah. I guess the idea is to be able to put your stories within another site that you've designed. Yeah, cool. Yeah. Thank you, very good. And my question is, I see you build a component using just plain JavaScript without using the React and Vue.js. So I think then we need to just using the plain HTML template to use your component. So in this way, can you share some like a downside using vanilla.js or benefit to get in this way without using React and Vue.js? Thank you. Yeah, for sure. So yeah, so like a lot of design systems will provide, yeah, basically like multiple alternatives. So you could have a design system which has like a React version of a component, a Vue version of a component, a vanilla or whatever it is, you could just keep making them basically and you could have different files inside the design system and just have instructions on how users can import each one in depending on their framework. And you could have it all stored inside the same NPM package as well. So the code could kind of leverage itself. So we're doing that with a couple of components as well, like depending basically if it makes sense, we might include a React version as well. But yeah, so the vanilla JavaScript approach is kind of awesome because yeah, you only really need yeah, the HTML markup as you said. So like as long as you've got the right markup and all you need to do is just follow the code example in the design system. And you need to initialize that JavaScript somehow. So like say you wanted to, like that accordion example, say you wanted to use that in React where you just create a React component which replicated the markup and like on one of the component initializing cycles just call that vanilla JavaScript and then it's kind of set up ready to go. That way you're using the same vanilla JavaScript to power the functionality of the accordion so you don't need to duplicate the functionality inside React with the component life cycles there. Yeah, the accordion is just a really simple open and close. So it kind of makes sense to do it like that. I guess like more complex components you would want to have React versions to get the extra functionality React gives you, yeah. Yeah, yes, that makes sense. So from a basic point you have the HTML version first and when we need we can add React or Vue.js supporting because you have already split them into small packages, right? Yeah, yeah, that makes sense. But when we have very complicated component, it's just sometimes if you're just using HTML you need a lot of HTML and put all the data in the HTML before running the JavaScript. In that case, we maybe need to think about it as a support. Yeah, yeah. Including like a React component is nice because you can get the, you don't have to, at that point the people implementing the design system don't have to worry about the markup because you can just include that in your React component ready to go and they can just add a button in and they've got all the correct classes. And yeah, you could even, like with the accordion you could even have a React component that leverages the vanilla JS anyway that's got all the markup done, ready to go, yeah. Yeah, thank you. Really helpful, thank you. With your design system how do you handle the exceptions of when you have all your system already organized, show everything, but how can you handle all the exceptions or personalization of your design when it's mainly for that client and it looks similar, it behaves similar but there's always something different or unique to your design that you already built. Yeah, so yeah, there's a few, like there's a few different approaches there, like I think the go to approach is to use like a variable system where like we're using post CSS variables for that. So there's like a post CSS variables file which has got a whole bunch of things that we can tweak. We can tweak things like color and typography, spacing, grid styles, that kind of stuff just by inputting new variables and that file just gets included in that project. So that makes things slightly different. It's not mainly in terms of kind of colors and typography, it's within your structure of your design. How do you handle those exceptions or uniqueness if you want to either keep it for that client or not to handle us in your distribution package? Yeah, yeah, so yeah, I kind of see that, like you've got the design system as the underlying level there. So depending on like how it's designed and what it looks like, it's got a lot of like assumed rules and that's where like all the spacing and stuff comes in and then you've got like, then you've got that variable layer sort of in between and then there's like the layer at the top which is really just like for a Drupal site, it could just be the Drupal theme and it would have its own CSS on top of that and yeah, designing it in a way that you can have that CSS at the top, not necessarily overriding things but just kind of working on top to add like a new, like a new customized design. I think that's quite possible. It's a bit of a tricky balance. You don't want to have to be like constantly overriding styles and changing things just because the design system specified in a way. I think it's key to in this situation when it's getting reused for project sites and client sites, keep the design system as simple as possible. Don't be like overly prescriptive with the styles, just like get the base things in there that you need to allow customization as much as you can with variables and then yeah, build it so that you don't need to override stuff and you can add that extra layer of styles to personalize it and you wouldn't necessarily use like all the components. I guess like you just add in some new custom components as well. Like it's kind of like the one-off stuff I was talking about before, like if you've got some design, the design system can kind of inform a lot of the site but you might have like a completely customized hero and navigation and header and all that kind of stuff, you know, just to keep it unique for each client. Yeah. Oh, I've got a few minutes left if anyone has a burning question. No, cool. Thanks, guys.