Tejas Kumar

Changing The Game with Developer Experience

ConFrontJS 2022 / 25:16

Watch this talk on YouTube

Transcript

33 paragraphs

This is an automatic transcript of the recording above. It is published in full and unedited, apart from correcting names the recogniser reliably mishears. It will contain mistakes.

00:00(Closed captions provided by Prisma) - I'm so excited to be here and talk to you today about things that I'm just really fired up about. Let's get into it. Let's start with an introduction. So, hi, my name is Tejas, that's pronounced like contagious, or maybe in pandemic times, advantageous is probably better, either way Tejas. Say it with me Tejas, right? And I work at a company called Xata. It's brand new. And you know, I guess if you want a short intro to the company, what we're doing is, we're trying to make databases really approachable and worry free, right? So like to provision or to scale, or to maintain a high level of availability, all of these things are quite hard and we're trying to just make databases easy and good, right?

00:51And part of that is developer experience. So I serve as the director of developer relations, developer experience falls under this umbrella. And that's why I'm here to talk to you about developer experience, but we're not here to talk about Xata. Our product is closed beta. We're not looking to like sell you anything at this point. What we do wanna talk about is documentation. You know, we believe docs are so essential to everything. And really for us, the name of the game is, world class developer experience. In fact, that's the title of this talk, world class developer experience through evergreen documentation. That is a mouthful, in fact, that's why the slide is so much simpler, just wouldn't fit, but that's kind of what we're trying to do.

01:29We're trying to create a world class developer experience with documentation and with our product that is yet to be mainstream, right? So to do that, we got to thinking, how can we do that? Because really we believe that docs are key to good developer experience. That is our motivation. That is our thesis statement. If you are a developer and you're referencing documentation, there's a high chance that either something broke and you're looking for a fix, or you're trying to figure out how to do something and you consult the doc. So you come for answers. If you come for answers and instead you get friction or you get like, Hey, create a GitHub issue with a minimal repro, whatever, you're like less likely to follow through, you're gonna be like, oh, I don't know, maybe I'll just, you know, abandon this in favor of something else.

02:18And so we believe that docs really are essential to good developer experience. And so in our process of trying to find, okay, how do we get like world class developer experience in our docs? We started with kind of identifying problem areas most documentation sites have, specifically more at our stage, like we're a really early company where like 10 ish people and you know, we're building fast. And when you build fast, we kind of thought about what problems arise, right? And what we noticed across the board is that, docs are often at our stage when you're moving fast, number one, slow. So you deploy some website. You hope it's fast, but sometimes it can fall behind and you deliver like documentation results in maybe a bit longer than a user wants to wait.

03:06And you can understand how this might be a problem, because if someone's coming to your doc site, they probably want answers really fast, but if they see a spinner and they have to wait, they're like, oh my gosh, I'm already annoyed. Can you please give me the answer? Well, you want to avoid that. We want our docs to be fast. So docs are often slow for number one, number two, they're outdated. Like if you move fast and break things, there's a high probability that your engineers tend to build features and stuff without updating the docs. It happens quite often that you either forget to update the docs or you just wait until a release or something and your docs kind to fall behind. We've seen this pattern quite a bit and we recognize that this is a problem we want to maybe address.

03:45Number three, docs are what we're calling impact-opaque. And I know that sounds a bit odd, but what really means is it's often hard to find out if your docs are actually useful or conversely, if they're unclear and maybe need clarification, right? I know some horror stories where people go looking for answers. They go to a documentation site hoping for finding an answer, and instead they just find like to do or TBD in the docs. And how then can somebody ask for clarification? Would they have to go to GitHub, open an issue and start a conversation, ah, that's way too much friction. Can we make that simpler? And so that's our mission. We wanna really solve these three problems with our documentation.

04:29And so with that, I wanna say our docs are, and this is very aspirational and hopefully true, but generally more aspirational than anything else. We wanna say, our docs are fast. We want our docs to be fastest is paramount. If somebody's looking for an answer, looking for help, they need to get it like immediately. Number two, we want our docs to be up to date, right? None of this like stale stuff, none of this, oh no, we forgot. Or we're moving so fast shipping, we forgot to update the docs. No, our docs have to be always up to date. Number three, we want our docs to be impactful. Like if something's not clear, or if we're using some acronym that people aren't familiar with, if we use like ACID guarantees somebody's like, what is ACID?

05:10We want them to be able to quickly ask for help and get it without, you know, open a GitHub issue with a repro. We want to provide that as frictionless as possible. And so with that, let me just walk through some of these in a bit more detail and then we can look at how it works. So when I say our docs are fast, what does that mean? How are we going about this? We want our docs to be fast by giving people text files. We believe really this is a superior because if you have a Static Site Generated or SSG, you just end up sending text across the wire and this text files can be stored on a content delivery network or on a CDN and can be served on a, stored, rather on a CDN node that is really geographically close to your customer, to your user.

05:56So what happens then is minimal latency, right? There is no server work that needs to be done because it's a text file, it's already generated. There is no client work to be done. So you're not going to open a page and then it starts fetching something. They get text, they get answers, instantly. So we are a huge fan of this static site approach and serving things from an Edge CDN. And really this would've been way harder if we didn't have a lot of help from Vercel's offering. So let me just adjust this slide here. We wanna say thank you to Vercel publicly for their great work on Next.js and their Edge that helps us serve our docs really fast. How about the other one? How about keeping our docs up to date?

06:41Oftentimes when docs fall behind it's because engineering teams work hard on engineering, and that's a good thing, but the issue is we update code, we update our git branches without updating the docs. What if we automatically generate docs from code? That's what we're doing essentially. We'll look more in the details of how we do that. I'm really excited to share that with you, but yeah, a lot of our docs are just generated from code and that solves the UpToDate problem. When an upstream repro containing code is merged to main, our docs just update based on that. Number three, we can make sure our docs are being impactful by tracking the impact. So we have a few things in place that allow users to very quickly share feedback with us.

07:32This doesn't work, I think this could be clarified. Here's a screenshot. We have things on the docs side that make this easier for users to give us feedback that then we see we iterate and then we reach out to the user and say, Hey, thank you. We've updated it. So with that, I think I've been talking too much. Let's just, you know, let's look at the doc site, right? And then we can go from there. So let me just quickly share my screen here and we can look at what's happening. To share my screen, yeah, let's switch over to the laptop here. So nothing special. Let's just open a browser and go to docs.xata.io. Now this, our product itself is a closed beta about the docs that is open. You can poke around if you want.

08:15And we had three things we talked about, right? We talked about fast. We talked about up to date and we talked about feedbackable. So how is this fast? Let's take a look. So if I reload, I mean, don't blink, right? Like it just loads. So if I click on a page, what we're gonna see is, it's going to be relatively quick. There are no like major bottlenecks that just kind of snaps around. We do have a progress bar just in case, but generally it's quite quick. But don't take my word for it. Like if we take, let's take this and like do a little Lighthouse audit on it. So if I go here to Lighthouse and just kind of run a report for those of you who aren't familiar, Lighthouse is something that does audits.

08:56Like it checks your website for many different criteria, like performance and SEO, and gives you a report. And as you can see, we have a 100 out of 100 score on Lighthouse that is as fast as can possibly be considering all of the core web vitals. That's what I call impressive. And because it's so fast and we're missing a bit in accessibility, that's just because of the background color of this, it's not contrast enough, we're working on it, but it's a perfect score regarding maybe minus those two points, because we care about performance. It is fast. It is quite fast. Similar scores on webpage tests and other services will reveal as fast. You know why it's fast? Because it's just a static HTML file.

09:38It's literally like here. This is the, it's just HTML. It's HTML that's cashed and served from a content delivery network. It's fast. Number two, up to date. How is this up to date? Well, we, as part of our offering data, we provide developers REST API. As you can imagine, REST API has a number of endpoints and a number of methods on those endpoints. Now to kind of keep our REST API up to date and our application up to date, we describe our REST API using a standard called open API. It's kind of like the graph QL, SDL, but for REST APIs, if you're familiar, it allows you to just defined like every endpoint, every operation, and then our backend team uses the same document to then implement against it on the backend.

10:24Our frontend team uses the same document to generate like an SDK and a client and the doc site uses the same specification to generate doc. So if you look at our API reference here, literally all of these endpoints have stuff that's written not by me, but by the teams that work on the API, this is literally straight up from GitHub. So create database branch, boom, all of this, I wrote none of this. Our docs, people wrote none of this. It's automatically generated. That way what something is merged to main our doc site updates with the latest API and then the backend also updates to implement that, the front end updates implement that. Everything follows. It's phenomenal. It's phenomenal. Lastly, feedback.

11:10How do we do that? I'll show you two ways. Number one, let's go to, I don't know. Let's go to schema and maybe you don't understand something, right? Maybe you're like, what is JSON, I don't get it? So the moment I highlight this, you can see, please clarify this. You can see copy link and copy text. If I click on, please clarify this. Let's look at what happens. I click on this flagging and it says, thank you, we've notified the docs maintainers. So now if I go to the repro of this thing, okay. And I go to issues, I'll see a new issue clarification from doc site. And it says, please clarify the following JSON on this page. Boom. So now I know, Hey, somebody had an issue with my usage of JSON on that page.

11:51I'll go expand it. There's an issue instantly for me to go, or whoever's working on docs to go fix it. Incredible. Let's look at, let's go a bit deeper. I'm gonna close that though, because I just made it. That's one way, what I can also do is, you know, if I scroll down somewhere and I like this type of data, right? So if I copy a link to this and if I send it to my friend, what'll happen is it'll literally scroll to it and highlight it. Oof. So you can imagine sharing doc's references becomes way easier, but above and beyond that, let's now say, you know, I have an issue with, I don't know, column types, something's wrong. So I can click this little feedback button and I'll say, column types is weird.

12:35Do I wanna include a screenshot? Yeah. So if I click this, it literally asks me like, what I want to share this tab, another tab, another window, my entire screen? I select one. I click share and you know, focus the window, takes a screenshot and I click send, and just like that after uploading a bit, it says, thanks, we'll review this again. I go to my issues here and have a feedback form with, look at that, look at rich feedback. And so we know what people need help with, right? This is what we mean by world class developer experience, it's like in service to developers, it's fast, it's up to date and they can share with us room for improvement. Incredible. Let's look at some code since we're here anyway, let's look at the code that makes this work.

13:30So if we, let's just open visual studio code to the docs repro. Let's move this over here. Okay, so let's talk code. So this is a Next.js application, as we said earlier, thank you to Vercel, we appreciate it. If you're familiar with Next.js, you kind of sort of get how it works, but if you're not, I'd like to tell you a little bit about it now. So if we go to docs.xata.io as a Next.js app, you'll notice if we go to like slash concept slash branches that maps directly to something in pages. So every file in your pages, directory maps to a route on your website, but you'll notice there isn't any concept branches here, but instead this thing, a spread syntax, slug. What this is, is actually like a catch all for everything at the root path.

14:21So it receives as a parameter, this slash concept slash branches, it's one react file that receives that as an argument. How then do we generate like 50 plus pages based on this argument? That's what we look at here. So if we look at the implementation of this file, there's just some, you know, some meta tags here and something that renders marked down and a popover, by the way, this popover is, you know, this thing here, right? But really the magic is how we take this one file and generate like 50 HTML files. Let's look at that. So what we do is we export a function called getStaticPaths, getStaticPaths receives, it actually reads the entire directory of content for MD files using glob. And as you can see, your content has a bunch of markdown files, okay?

15:14So it gets just an array of strings that represents a markdown file here. And what it'll do is it'll generate one HTML file for every element in that array one path as you will, for every element in that array. So at this point, if I was to just like create a new markdown file here, it would automatically get a route here. So the people who are writing the docs, they don't really have to touch code at all. They just write markdown. It magically appears. So it maps MD files to paths and then get static props receives a param. And of course, this is param here, right? And what it's gonna do is when it receives param, it's going to just read that file, read the markdown file and pass the contents of the markdown file as props to this component here.

15:59And what do we do with that prop? We just put it in a markdown component that makes things bold and italic and formats as needed. That's it. This one file that's less than 70 lines of code gives us an entire site that is statically generated from markdown. It's incredible. And because it's statically generated, it's fast, it's fast. Let's look at the code generation piece. So if we, let's actually first look at the thing that describes our open API spec, that describes the API that the backend teams and the front end teams use. So if we go to our internal repro of open API, okay, what we'll see is, we have, this is it. And if we go to public, we have this like massive Yamo and like really, really large JSON file.

16:49And by massive, like I'm not joking. This file is like 3,500 lines long. It's intense. So what we do is we use effectively GitHub as a CDN. We fetch this file using the GitHub API. We have a little function in the code called get open API, get open API reference. And this is kind of what it does. Is it, you know, checks if we're in a fork of Xata or not, but like if somebody forks it and we use their fork, we don't wanna generate stuff, so if it's owned by Xata we do just a little security check. We get the file. Literally the public open API file from GitHub at a branch. And we validate it using an open source library and just send to JSON, right? That's it. So if you go to the doc site slash API slash open API, what you'll see is a massive JSON file.

17:42That's literally the same as this. We just get it from GitHub and serve it to ourselves. And then we use it to give content to these pages. We can actually look at that. So if we go to API pages slash API slash open API, what we'll see is, we encode it cause we want it to be fast. And for the sidebar, we get a different thing. Literally just a data structure that maps well to these menu points here in react. And then for not the sidebar, we get the open API reference and just deliver its trade through. You can actually see this being called here on the site asynchronously. So if I go to network and refresh, you'll see a call to slash open API where we are actually getting that API endpoint.

18:30So yeah, so open API for sidebar and what do we get? We get grouped by like category by branch database table. We get a bunch of endpoints and we can actually see that here. So we have users first. So if you go to slash users, each of these is just in a map in react. I mean, if you're interested in the frontend code, I think I can show it to you in a sidebar. Yeah, it's just a map. So menu items dot map and some stuff here, right? So that's how we generate from JSON, our API reference. But I mean, even more here, like, let's go a bit, the extra mile, right? And if we go to a pull request again, this repro, I don't even know if I'm allowed to show you this, but here, this is a poll request that changes the spec.

19:16We even provide a comment in this so they can see how this affects the doc site. This is main, that's the change after this PR and this is a visual diff that will highlight things that change in the doc site. So it really shows the of up updating the spec. And I can preview the doc site at this branch of the spec using that link, right? It's incredible. And this is really going the extra mile to make sure our docs are always up to date. We're really proud of this. Let's talk about feedback and wrap this up. In terms of feedback, how are we making sure our docs are impactful? We already looked at how they work, but let's look at the code. So as you can see in our main like slug file, that is every markdown page.

20:03We have a pop over that's lazy, loaded, it's lazy, loaded 'cause we don't want to load five kilobytes for no reason. So only when someone highlights this shows up and we load the react text selection pop over, that's an MPM library that just gives you a pop over next to your tech select. And we render this thing here and it's just, you know, it's just some dumb, it's essentially you can imagine the HTML code for this and on click handlers. So that's the popover. And lastly, let's talk about this feedback button. This is quite cool. So if we go to feedback button. Feedback button, we have some state is giving feedback. If it's true, we render the whole model. If not, we just render the button as evidenced by here is giving feedback and then you get this huge model.

20:49But what I wanna highlight, I mean, this is pretty standard in reactive text area. What I wanna do highlight is this screenshot functionality, because we like it quite a bit. How that works is we have a piece of state called Should Include Screenshot. We have an effect that triggers when this changes. So if it changes, if shouldn't include screenshot, then we take a screenshot with a sound effect and we set it in state. Essentially, that's it. And if you deny permission, we also show a nice error. I think, let's verify that. So if I cancel, yeah, well, I just, they don't show an error because I canceled. But if there's another error, we show that. This screenshot is an open source library we've created, you can NPM install it and it's literally what it sounds like.

21:32There's a function take screenshot. Boom. One last thing is we don't show this checkbox at all on mobile devices and that's because the library exports a function. And as we see here, if that function is false, we essentially don't render the check box at all. Let's just search for a checkbox. Exactly. And so is browser compatible and then we show it. Otherwise we don't. And finally, how do we send it to GitHub? We have send feedback as an API route and if there's a screenshot, it attaches it. And we send the screen to a file up like a paste bin. It's secure. We've done our math. We send it to CVSH. We get the URL to it. And then we post an issue on GitHub using the GitHub API. Now those are some technical details and really those are ways we believe we're providing what we hope to be world class developer experience with docs.

22:30Let's quickly now talk about some takeaways. So we've looked at code already. Let's talk about takeaways. So takeaway number one, a service mindset we find for developer experience is crucial. Like we really see ourselves as servants of our users. And I think really for developer experience or DevRel it's really important that we see ourselves as servants, right? We wanna have a service mindset. We wanna make it extremely convenient and frictionless for people to get done what they want to get done with minimal steps in between AKA friction. So adopting a service mindset versus is absolutely crucial. And we'd recommend it for your DevRel game if you haven't already considered it. Number two, set a high bar, like for us, we set probably the highest bar with developer experience.

23:24We want it to be smooth. We want, like a lot of, we've seen a lot of things where, if there's some error and something doesn't exist, say a CLI, right? Then the CLI will just tell you, there's an error here. We want to set a higher bar. And instead of just tell you, there's an error, ask, shall I create one and give the user some actionable stuff they can do in the face of errors. So for us that's one way, but we really believe setting a very high bar for DX and service is really important. As long as of course it doesn't cost anyone, you know, their health, we still wanna be responsible with burnout and so on. But generally we set a really high bar. If we miss the moonshot, we at least land among the stars, right?

24:09Number three is reducing human error. Look, we're in a pandemic, we're tired, we're frazzled, we're burnt out sometimes, we make mistakes and it's totally understandable to make mistakes and get things wrong. And that's why we are reducing as much opportunity for those mistakes as we can by offloading things to the machine. One example of this is co-generation from an open API spec. Sure, there may be human error, like in the spec, those can be pull request reviewed, but the error of like not updating the API reference when the API change is fully mitigated. So we look for opportunities to reduce and mitigate human error as much as possible and take full advantage of that. That's kind of all I have for you.

24:56I hope this doc has been meaningful and has helped you in some way, if it has, I'd love it if you could at me on Twitter or comment and let me know, but for now I wanna say thank you so much for your time and for letting me be a part of this. I appreciate you. And yeah, I'm looking forward to talking more with you. All right. Peace.

Elsewhere

There is every talk I have given, all 80 of them, ConTejas Code, the podcast, and Fluent React, the O'Reilly book on how React works inside.