 So, good morning everyone. Still sleeping, I guess, people are still sleeping and most of us are still fighting with Bangalore traffic. But yeah, let's start with this thing. So, today I'm going to speak about building for developer experience. So, just to clear things up, all the thoughts are mine, they don't represent anything, they don't represent my organization or something. These are just my experiences by building a design system over last year and a half. So, we are building, we are building applications. But they never used to be applications, they were just webpages and we used to design them, not build them. In last decade or so, all the complexity of application had moved from back end to front end. And yes, today we build applications and they are not mere applications, they are experiences which we provide to our users. So, I'm going to ask myself like, how do we actually build application and experience? So, let's take a highly contrived example here and I would say, we start with a need, a requirement, a gap which our application can fill. So, for sake of argument, let's say a user needs a swing and our product team is on it. They started brainstorming, they come up with a perfect swing. They thought of everything, security, robustness, experience, and had a vision of like what a swing would look like. They handed it over to the design team. Design team spend days in designing a pleasing experience, a comfortable swing and it's beautiful, it's beautiful. Thought about comfort, aesthetics and it was evident in the design. It's ready to be built. Wait, we have our architect team also there. They want to future-proof the swing. The architect spend days to create a technical design which can sustain future requirements and grow as requirements come in. Yeah, I guess perfect. We have a robust swing there. Can we build it now? Yes. So, we collect all the requirements from different stakeholders and throw it on the design team, on the development team. So, the development begins. But there's always a deadline and deadlines are pretty squeezing ones. The development team cut some corners to get something out really fast. We have a swing. But user wanted something really simple. We somewhere lost the requirements in thinking like, somewhere we lost in the communication what user actually wanted and the reality was far away from the expectation. Ask why? Why we are so away from what user actually wanted? So, there are different stakeholders in building experiences. There is user who is wanting or who needs something. Then product who is trying to fulfill all the needs of the user. There's design who is trying to provide aesthetics and ease of use to the users. And then architect who wants that project should live long. It should grow with the requirements. And all those people combine everything and put on the poor development team. And they somehow build something. The development team will start filling slugs. So many people are just throwing requirements at me and they might leave the company. Another development team will come in and they'll try to improve what they have. They might also feel something. Like, eventually we'll get a usable product. So, where I'm going with this thing? So, when I'm preparing for this thing, Jainav asked me, where does DX stand in the universe of user experience? DX, a developer experience. So, there are three key stakeholders in every experience. There's user, there's product and there's design. And when they interact with each other, like when user interacts with product, you get understanding, you get requirements. When product interacts with design, we get the interfaces. When design interacts with user, we get experience. And when all three combine, we get developer experience. Like, that's the white center, the white at the center is something which is interacting with all the stakeholders and trying to build what everyone is thinking. And more the interaction, you get better experience. And we have something ready. Yeah. So, eventually user gets this thing. It's not perfect, but it's very close to that. And this was our component library in 2018. So, let's get real. Like that was, everything was hypothetical. Let's get real with extra examples. So in 2018, sorry, in January 2017, we started with a design guideline. It was called Unity. And we come with buttons and everything from design side. And we implemented it quickly in React. We started using it. Was good. Websites were looking good. Design was meant for supply chains kind of uses and it worked really well for us. Down the line, within the years, a new designer come in with new thoughts, new thinking, new colors and everything. And we got different buttons. So, that was the first time when the system broke. And just three months after somebody, some, one more design came in with a different guideline, different buttons. Basically, I'm taking example of buttons as they are like the primitive thing when we talk about building our website. So, just after one year and three months, we had three buttons. More three months, one more button was there. Next month, there are more buttons. Next month, there are more buttons. And within a year and a half, we had so many different kinds of buttons. Like it was going out of control. Everyone was putting whatever they wanted. And if we go back and see, it started with a small inconsistency. Somebody came with a new idea. New ideas are not bad. But if it's inconsistent, it starts with a small ripple effect. But it's given the time, it propagates and hits product as a tsunami. And yeah, tsunami blocks the user experience. And it is caused by a very tiny inconsistency in the system. We developers start calling this thing, the system is legacy is broken. And we hate to work on legacy systems. We try to move away from those systems. And somebody would propose, let's rewrite everything. Yeah, why not rewrite everything? Don't take me wrong here. Like, our rewrites are good. But the reason behind this rewrite are unjustified. We actually wanted, we don't want to rewrite. We are rewriting in this scenario because the project feels very legacy as we are far away from the consistent experience what we started from. And we don't want to run in this situation. Is it possible to avoid such a situation? Yes, but if you have ever written a piece of code, eventually it will grow into an unmaintainable beast. And we can't do anything in that respect. Like we are limited by physical laws here. Our second law of thermodynamics is entropy of an isolated system can never decrease over time. So our code is going to be bad eventually. So what do we do? Well, we can inhibit the rate of entropy. We can slow it down. We can increase the longevity of software. It can run little more. So how do we do that? Over last year and a half we found something like which helped us really well. Most important thing we found was the communication. Communicating all the decisions, all the ideas better can reduce inconsistencies. And another thing we found was visibility. I'll go to that, I guess it's very big. Visibility is really big. Then accessibility. And when I say accessibility, I'm slightly different from the general common pursuit winning of this word. We go in detail in a bit. Adoption and feedback. Feedback is the most important one. So let's start with communication. So we cannot collaborate without communicating. And building products, building experience is a collaborative task. So we cannot avoid communication. And if you say like communication is kind of basis of human civilization. So we are already communicating for centuries, for millennials. So why I'm talking about this? Yeah, we communicate, but there is ambiguity. And ambiguity in communication results in misinformation. Let's take a scenario. How open you face a situation when a product manager comes over and says, make this test text a little bigger? I guess pretty often. And what does it mean by a little bigger? What is little there? Is it one pixel, two, four, 16? Like more importantly, our engineers are hired to increasing or decreasing text sizes. This is not what you really want to do. And this ambiguity in language results in inconsistencies. The goal here is to understand what little bigger means and limit it. So we need a common language. A common language with product design and engineers can speak. Let's say we have a common language. Now, if the product manager comes and say, make this font whatever in our language, whatever the little bigger is, but why, why you make this thing a little bigger? And honestly, are you gonna ask why? Because you don't even, you don't have a basis of asking that question. There is no ground rule which says this text should be this large or something. So we have to define some design principles. We have to define all the vice. We have to write them down so that we can move away from unnecessary communication and unnecessary dialogues and actually build products. So that's what, that's what, that's the first thing we did. So we started with defining all the variables all. The color, sizes, everything. And we did, started in CSS, like CSO language you're already using and these values, they are building blocks of a design system and often people call them design tokens. So tokens become a basis of the communication and we started looking public design, all the public design systems, how they are actually managing tokens. We looked at Atlassian's design system, Polaris design system by Shopify, Lightning design system by Salesforce, and we found like our Lightning design system talks extensively about token management and our initial implementation was highly, highly motivated influence from their implementation. So we started storing our tokens in CSS variables. But we needed some configurative. We were using these variables again and again and we were kind of creating aliases. So this approach in the beginning worked for us, but eventually it presented some problems like CSS variable depend on scope of the DOM tree. So you cannot statically determine like if that variable exists in the scope or not. Then the problem was repeating identifiers. Every time we are creating an alias, we are repeating the same identifier and it adds a way to CSS payload. Plus they are runtime failures. You can never know if that variable exists or not at the build time. Hence, we thought, let's put a pre-processor in there and how do we pick a pre-processor? There is stylus there, it's new and shiny. Should we use it or use both CSS? It's all built upon CSS, we can use that. Maybe less or less. So many choices, really difficult to pick what you need. So we had to understand first like what we actually wanted. So we started like, we need a system which provides us compile time variables so that we can trim down all the identifiers in the final build. We needed something which provides easy reuse of variables. You need something which is stable and has good ID support. And it should definitely provide strict compile time checks. So you're leaning towards SAS and then find a founded token management library called account remit. It's an awesome library built by Miriam Suzanne and the team, it's written in SAS. So aligned with our preferred pre-processor. And it supported aliasing really well. So from this, we went to SAS maps. And what account remit allowed us to create aliases. So we were basically referring all the tokens in scope of where they're used, like background color and button become namespace, button color, you see button color and background color and it was referring to the primary color defined in the same map. So, and this is type safe. So when we build this thing, if that hash primary doesn't exist, it will fail at the compile time. So we picked SAS and started implementing all the tokens using tokens in CSS like this. Color is a tiny helper which allows us to access tokens from this color map. And we started building everything like that. All the padding sizes, margins, typography using this thing. So the two rules I wanna highlight here is account remit, the word is the company's you works in. So this is a really nice tool if you are maintaining your tokens in SAS and if you want to support multiple platforms and have a centralized token, so Theo is really nice by Salesforce. It allows you to put your tokens in YAML and then export in SAS, CSS for Android, for iOS, for Windows, for basically everything. But we preferred account remit because it was aligned like we were building only for web and we didn't want to introduce much complexity in the system. So we picked account remit and now we have a basis for our communication. We have tokens. Now, when we say make it little bigger, we don't say make it little bigger. We'll say make it H4 or make it H1 and that typography style, the height of the font weight, the font height, color and size, everything is defined in the system as tokens. So we are talking in terms of tokens but next we define some rules, some principles for our language. So it was basically a list of dos and don'ts, like don't use primary color as text color or don't use dark text on dark background and they were written in plain text and for different kind of tokens, we kind of created a static website and it listed down what are they doing. So we did this for small tokens like colors and sizes and when you can use a particular token, what does a particular token mean? We did it for our components, like when you can use a component and how you use a component. If you're looking for examples, Google's material guide does it really well. Like this is, I'll see is the best principles collection you can find on the web. They have listed down all the dos and don'ts and with actual examples and screenshot what you should not be doing and this helps really well in having an ambiguous communication. So our product manager or designer won't have to come to you, tell you that you should not be doing this. You already know what is allowed and what is not allowed and our principle cannot be covering everything. It's actually an ever evolving list and I'll come back to the point in the feedback section when the fifth point I showed you earlier. So next thing is visibility. So you might have heard of a phrase like if it's not documented, it doesn't exist and it took the word to its meaning and followed the same approach. Like if something is not documented in a system, it doesn't exist. So how did we lend here? So we had a drop down component back in 2017 and it kind of behaved like select, estimate select element, slight different UI. But after some time, people introduced their designs and do some differences in designs and developers basically started implementing slight different variants and within a year, we had four components doing exactly same thing. It's slightly different UI. If we had visibility, what this drop down component was actually doing, we won't have created all these three components which are actually doing same thing. So we spend lots of time on like, what should we do to avoid these kinds of things? So we started simply listing down all the components and basically if you need a component and come here, search for it, if it exists, you can pick it and work with it. Another thing we added was, we started keeping version numbers. Like in what version of library you can find this component and what is the status of this component. We define some principle for statuses. What is deprecated, experimental or reviewing already and what can be used, when it can be used, what you have to watch out if you are using something. It really helped us, so it really helped us in better uses like people could see what are the components available. And next thing we started was publishing change log. This was real important. People who are using our experimental components, they want to know what is actually changing in this particular version. Do they need to update in their application? So our writing change log was difficult. Then you find a tool which can do this automatically. It's a tool called conventional change logs standard version. So standard version can look at your get commit history and generate a change log out of it. But now there's added responsibility here. We have to keep our history clean and concise. So we created again some principles, as discussed in communication section. So the principles in place were, we accept changes via pull requests only. One pull request can propose only one change. It can be a bug faces, it can be a new feature, it can be a component. It can even be a documentation update or dependency update or some tooling configuration change, anything but one change per pull request. And we started squashing over pull request and followed the commit message guideline provided by semantic commit messaging. And we got pretty decent change log, which were really helpful in adoption because people could know what is changing in this particular version. Do they need to change in their applications or not? So then towards visibility, what we did we created a documentation page for each component. And purpose of this thing was to highlight all the relevant information required on the component, what is the quality status and where is the source code for this component. And we also included some preview. We include examples, which you can look at. We also provided API. So our system was react-based. So we extracted, so it was react-based and we were using TypeScript. So we extracted API documentation out of the components and presented in the component or function itself. And then on project side, we did for maintainers who are maintaining this design system, we added a few more principles like our naming status for component. The file name should be exactly like component. So if you search in ID, you get only that component. All the files related to Banner would show up. Instead of using index.es or something, we are using the file name as component. Since our library has around 50 or 60 component, this cut down, like when you are working on multiple components, you are jumping across files. And this small principle helped us to cut down large amount of time wasted in switching files. Then we decided to co-locate our documentation along with our source code. The readme file you see there is actually the documentation. It has everything. It has all the text and all the examples. And you basically picked this markdown file and deployed it. And all the code examples, we embedded an editor so you can directly see what is the code that is renting that particular example. And let's look into a component. This is what a component looks like. We had, again, a small convention, like every component should have a props interface where we are defining all the props and we are inlining all the documentation using doc comments. And this thing is extracted out and can be presented in multiple ways. So the tools we use for this thing are ReactDocs and TypeScript. So this library can extract all the prof information from component. And we combine it with Doctrine to add more information, like when this particular prop was added. Like there's a since tag there on Icon. So the Doctrine can extract all those tags and we combine this thing to a webpack loader so when we are building our documentation, it can attach all the information directly with the component and we can present it in a table like this where we know Icon was introduced in version 1.6. It would be available only when we are using that particular version. So yeah, this reduce our maintenance effort. Like we are getting documentation, our documentation always in sync with our source code. If we are making any changes in a particular component, documentation is right next to it. We made sure like you are updating documentation in that same PR. Next thing is accessibility. And the meaning of this word is slightly different here. So what I mean by accessibility, the system should be accessible to everyone. Like it should be accessible to a product manager, a designer, a developer, or whoever who is involved in the building process. That is why our documentation look like this. There are no code examples here. It just a plain tag, like kind of look like an article with some examples and previews. But our developers need more information and they can basically opt in to see the API there. So who don't need all those technical information can look the component at its face value and understand and use it and like how to use this thing and when to use this thing. And developers can actually go and find the API and basically implement application using this component. As I showed earlier, there's a text editor where you can see all the code examples. And since you're writing in TypeScript, we wrote a small script which can extract type out of components. So we can do something like this. We can provide auto completion and prop completion in the embedded ID as well. I have a small demo. So this is the embedded ID. So when you start typing edit, you provide your suggestions. Yeah. And all the documentation you're inlining is extracted out and put in the browser itself. So tools we had used here was a Monaco editor. It's the editor. It is the actual editor which is used in VS code. And we combined with, we use TypeScript compiler to extract types, convert them in a form so that we can embed the types in Monaco editor. And you get similar kind of experience in applications. Yes. So this is a recorded demo. So this is how you would be building an application. You just start typing. It auto imports the components. It suggests what are the props available. It suggests what are the components available in the system and auto completes them. Auto completes props. Yeah. So it was way better than what we had. Like now we don't even have to jump to documentation to see what we really need. Another example. So this is kind of more of a, this example is kind of what, how we are building applications, building applications actually at Mentra. So we have lots of forms. So this is a form component. And it's designed in a declarative manner. So you have to basically do minimal amount of wiring. So this form component uses an object and uses context and all the child information to basically inject all values and all change handlers on the elements. So a design API in such a way that it reduce cognitive overhead on the developers and they focus on building applications, not fighting with the API. Yeah. Well, yeah. So you also try to do this thing. API across components should be similar. So when you are using multiple components, you should not focus on like, this component uses type for this thing and the other component uses type pro for some other thing. So we tried to basically have similar APIs across components. And yeah, that's how we build forms. It looks like plain as table and we are not worried about how this is getting state and all this to focus on your core logic of your application. And this thing, these things we get out of the box with TypeScript. We just have to wire up the tools in a manner so that we can basically utilize the ID in best possible manner. This is another example. So in SCM world, it's just tables and forms. You build a form and there's a table next to it. That's how our applications are. So again, we created a declarative way of defining tables. So the API is something like this. You tell what you need and you don't worry about how this thing is rendered. So just create a table, pass the data, then you define what columns you want and this component takes care of how to render those things. And all those UX guidelines and basically how to render a table, filtering, shorting can be contained inside this table. You just tell, you need a table and now UX decide how a table would look like. This thing with the design system team and now we can build experiences for them. The thing we did is we embedded documentation. Basically, we embedded the links to documentation right in the component. And so that you can basically hover over a component and click and go to documentation and see the digital documentation. Ah, adoption. So we always come up with new shiny things but business is value-driven. We cannot say this is new, use it. We have to show clear benefits and not everyone is interested in using new shiny things without benefits. And build this thing, it was like something like this. Like we have something for you but all the developers will know we are busy. So adoption is something which is quite tricky one. So how we tried to solve this thing is like any product. Like every product has an adoption cycle. They are some early adopters who are interested in new things. We identify those in our organization and basically peer program with them, help them to get few applications on boarded with our design system before we presented to the larger audience. And we spend like almost six months this way so that we can get few people using our system. And like these kind of things are more prevalent in larger organizations. For smaller organizations, I guess you can convince everyone to basically be on board this thing. And while adoption, like we have to most of the time step in, help them build their applications we did lots of peer programming sessions, training sessions, Q and A's. So prioritize whatever helped the end developers to build application using our system. And once we had few interested developers using design system, we got some numbers. And more of those early developers become proponent of the design system. They influence other people in their teams and around like they were building application faster. And those numbers, actual numbers are irrelevant here but on an average you are getting 400% reduction in time required to shipping new features. And when we presented these numbers the organizational people, they were on board. They wanted to do this thing for everything but tech is always a second priority. We have to run business fast. We are still in progress of adoption and I guess it will take another year and a half to have everything in Vindhra on the design system. Throughout the end, I wanna talk about feedback. So we had created so many things, like we have principles, we have tokens and we want everyone to adhere to them. It is possible that whatever we decided could be wrong. So the first principle in our design system was to embrace feedback. So anything can be changed but there's a proper channel. You have to convince people and you can change anything. If you feel something is wrong, you have to basically communicate about it, give positive feedback and basically whatever you are trying to introduce, what you are trying to change should become a new principle. Another thing in these feedbacks what we had was we were not deleting all principle. Like you come up with a principle which can supershade the older one. So we didn't want to delete that thing. That principle come out of a discussant and we don't want to lose that information. So we created a decommissioned principles list where we were putting all the deprecated ones so that in future you basically go back to the same thing and you can find like we already did this thing. We don't have to basically fall in the same pits again and reach to the same conclusion. So we can use this information. This information was really valuable and it helped us to shape our system. So like in beginning we started with very minimal things. We started with a button and through various feedback cycles, various to a place we have now 60-ish components which are being used more than a dozen of application. So it's all done here. Just quickly revise the things we talked about. So communication, we define tokens, reduce ambiguity and use principles to basically reduce involvement of people in decision-making process and we listed down all the principle as plain text on the website and we use a counter for token management. Then we talked about visibility. It was about providing, so making the information available to everyone. We use a combination of handwritten documentation and generated documentation. Use React, Doctrine, Doctrine and standard version for release management. We talked about accessibility. It was making all the information available to developers and everyone in their relevant environments at their fingertips. I don't have to jump through multiple hoops to get the information. We talked about adoption and the key thing I could get here is get some initial users so that you can get some matrices to show and to show the benefits and basically get everyone on boarded and feedback, listen to everyone and keep iterating. Yeah. So I tried to summarize my last year and half at MENTA in this talk. I hope you get something out of it. Yeah, thanks. I'm Rahul Khadiran. You can find me on Twitter with this handle. I rent about tech, JavaScript, view design system, local communities, diversity. So may we follow me? Thank you. We have very short time, only one or two questions right now. Hi, I'm Peter. So the question that I have is suppose you said 27 applications consuming your pattern library. Yeah. Common library. So how do you manage that you're on component library version 1.x and then you come up with some more complex UI elements that's kind of is going to bring in breaking changes and you release version 2.x and some newer application has taken 2.x but the older application also wants to upgrade. How do you take care of that scenario? Because that is going to be too much overhead on the older applications. Yes. So the approach we are going here is like you're trying to reduce the number of breaking changes we introduce but they are inevitable. So the thing we are trying right now and like I haven't talked about this thing, I'm trying to have seed in deliveries. So you can lock onto a particular version and we won't ship anything breaking in that and you don't even have to build your application again when we ship a new version of library automatically get it. But for breaking changes we are providing migration paths. We are using recast to basically create code modes. So you can apply those code. So whenever it can be automated, we provide code mode so that it can be automated. The migration workflow can be automated. But until now we haven't introduced something which really breaks in the existing components. Hello. So you gave an example of multiple versions of select component. How did you finally move to a single component and was it a hard move or a soft move like gradual transformation or did you change everything at once? So this was kind of, initially this system was kind of break everything as start from scratch. So how we are building right now is trying to contain the UX decision inside the library and give flexibility to basically compose together the UI you need. Just take example of the drop down or the select component. Now the logic of selection is in one component. The logic of list and drop down is another component and you can compose those two, three components to create what kind of view you need in your application. And all those views are already well tested by design and development team. So we have like clear examples if you want that kind of drop down in your application you have to use it in this way. So kind of creating patterns out of the library. So you can basically pick this pattern and put it in your application. You don't have to worry about how this thing is going to be. Like the end goal with the system was to provide all the developers with tools good enough so they can focus on their business logic and leave all the UI and UX related stuff on the design system team.