5 Years of Building React Table

Bookmark

Join me as a I dive into the history of React Table and discuss everything it’s taught me (both successes and failures!) since I built the first component-based version 5 years ago. We’ll cover tons of sub-topics including, but not limited to: .... takes a breath ... Headless UI, React Hooks, Advanced TypeScript, Branding & Naming-Things, Build Pipelines, Open Source Software, API Design, React/JavaScript performance and even Framework Agnostic Tooling!

by



Transcription


🎵 Alright! I'm excited to be here. I have a lot to cover. I'm jet lagged and tired, but like, I gotta bring the energy, so help me out. Like, we gotta bring the energy, okay? I have some t-shirts I gotta throw out really quick, and some people who are gonna help me. So like, let's just get to it. Here, take that one too. Anybody want a t-shirt? Over here! Okay, the loudest cheerer gets this shirt! Yeah! It was exactly the person! Perfect! I'm out, I'm sorry. That's it. Alright, I hope you like Jurassic Park. You might not by the end of my talk, because, I don't know, you'll see. My name's Tanner Linsley, and I'm here because I love React, and I love open source. And I'm kind of addicted to it. It's a bad addiction, but it's a lot of fun. Normally I'd be talking about React Query today. I'm not gonna do that. I'd rather talk about, take it back old school, the very first library I ever built that kind of took off, and that was React Table. I want to talk about the last five years of React Table and some things that I've learned through this crazy process of building an open source library, and maybe you can apply some of it to what you do, or maybe not. And it's just a fun talk. But we gotta go all the way back even further to 2015. I was invited to co-found a startup called Nozzle with some friends. And Nozzle is basically Google, but against Google. We are reverse crawling Google search results at scale, talking like billions of results a day. We're measuring them and extracting out all the data and just shoving that into BigQuery, believe it or not, and serving it back to SEOs and marketers who want that data. It's pretty cool. Part of that product is that we have to do a lot of data visualization, a lot of querying, and, of course, a lot of tables kind of coming together now. I wish our tables in 2015 looked like this. They did not. We were working with a little bit lesser tech here. Not quite like this, but this is where it all starts, right? Everybody starts with the HTML5 table because it's awesome. It really is a great element. Try building a table with divs, and you'll appreciate it. We needed to ship and sell and just, you know, hopefully like Svayzak Teller was able to teach us, like, have an opportunity to improve. So it was like go, go, go as fast as we could. We were using Angular at the time. Boo! And we were using tools like ngGrid and UIGrid, which honestly were fantastic. They were built in Angular, like for Angular, great integration, and we eventually got to use agGrid, which is also an amazing tool. There we go. We have some agGrid fans here. So something happened we weren't expecting. This framework shows up out of nowhere, and it's like this is it. Like this is where you need to be. We're like, okay, let's do it. Investment time. We moved everything over to React. I'm talking like everything in like three weeks. And then we got there, and we're like, crap, we don't have a data grid library. We're like, wait, wait, wait, wait, agGrid has a React adapter. We're like, we are saved. And guess what? We were. Like we were able to migrate and just keep using agGrid, and it was honestly super cool. But we did run into some little issues here and there. We were working with a React component. You know, it's just React. Everything is just components. But something was interesting. Under the hood we noticed agGrid was not rendering using React. It was shipping with its own custom DOM manipulation engine, which explained why it was so crazy fast, right? But in the process of shipping that crazy fast engine, React kind of got burned a little bit. There wasn't the level of integration we were looking for. Now, I'm really happy that as of like today, agGrid has like an integrated React render, and it's amazing. Niall from agGrid is going to talk about it like here in like a few minutes. So stick around if you want to hear about that. This is way back in 2017. Like, that did not exist yet, and we needed a table library immediately. So obviously I started working on React table. It was a single component. It was 100% React, and I was able to offload like a lot of stuff to React, all the rendering, the state management. I mean, we were still using this.setState, but it was pretty good still. We even had smaller bundles because React was doing so much for us. And we released it like thinking it was just going to kind of be whatever, and React table started to grow. People wanted tables and React to work together. And so while we were loving the success that we were having over on the npm downloads chart, a storm was brewing on the GitHub repo in the form of just issues, tons of issues. We were getting inundated with issues, and they all looked like this. Can I move pagination? Give me custom props. Can I use my own row component? Can I use whatever CSS and JS library is out this week? Can I do anything with the markup? And the reality is that I couldn't answer any of those questions. I didn't have the options to do that. Honestly, it was just this huge pile of crap. It was terrible. And I did the only thing that I knew how to do, and that's add more props. Any guesses how many props I added to React table version 6? Come on! 137 props to do everything. They're all right there to customize every little thing about React table because it was just a single component. I was drowning. I honestly was drowning. Luckily, I didn't die. But thankfully, while I was drowning in my misery, my friend Kent was over building a new library called Downshift. Downshift was a library for building drop downs and autocompletes. But it was really interesting. It didn't render any markup for you. It just gave you the state, gave you the API, and you had to hook it up yourself. I saw this, and I was like, this is the answer. This is how I'm going to solve this problem. Immediately, I dove into React table source code. I was like, rip out all this stuff. We're going to go with this API approach, invert control to the user to render everything themselves. Some people were like, you're going to make me render my own table? I'm like, yeah, I am, because it's going to help. Just believe in me, I promise. So I'm almost done writing this new version. The React core team is like, boom, hooked. And seriously, it just killed everything, like functions as children, render props. I was like, yes. This validated the exact approach I was trying to take. So I was able to take this dinky component as children as a function thing, and turn it into this awesome used table hook where you could just return whatever markup you wanted. It was fantastic. And we launched it. I launched it ASAP, as soon as it was done. React table version 7 was off the hook. But because of this inversion of control, I was able to close like 95% of the GitHub issues that we had, basically answering everybody with the same exact thing. You want to move the pagination? Do it. Do it yourself, I dare you. And I later learned that this pattern has a name. It's called Headless UI. And Headless UI is not the Tailwind products that you're thinking of, but conceptually, it's a process of taking all of your logic and your handlers, everything that makes up the logical parts of your application, and separating them out from your markup and your styles. I think that this encourages a lot more capability, inversion of control, reusability. I think it results in higher quality code, almost in the same way that moving your state into a state machine does. So we launched version 7, and it was great. It took a little bit of time for people to convince people that they had to write their own tables, but once they tasted it, they loved the power. That went on for two years, and I even started to see some projects like GitHub issues the new beta is using React Table under the hood to render all their tables, but they're using their own components, it's all headless. So they get to keep using their component library and all their styles and everything they're used to using. I saw this and I was just like, I made it. React Table is done. Checking out. I'm going to go build React Query. I basically did that. Open source has a way, though, of kind of screwing with you. You're never done with open source, and neither are your users. I really wish I had sound for this next slide, but I'm pretty sure Paramount Pictures would shut down the stream. Anyways, I'm over here enjoying my open source, and out of nowhere, it's like, boom, TypeScript users come out of nowhere. And they're just like, give us TypeScript, go, go, go! And literally I'm like, stay away! I had no idea what to do. It's a true story. I was closing issues and hiding, locking things. Stay away, right? If anybody's ever done open source and you have TypeScript coming at you, it's scary. If you don't know TypeScript, you're just like, I don't know what you're talking about. I'm sorry, somebody else can do the types. I'm just going to keep dinking around here. I had no idea what I was doing. It was scarier because I knew TypeScript was almost inevitable. It was coming for me, and at some point, I was going to have to have a reckoning. I resisted it so hard. I even bashed on it on Twitter. We all do it. Everybody raise your hand. We all do it. But I started to notice that libraries using TypeScript generally were higher quality, more than mine. They had less issues, and honestly, the developers working on them and using TypeScript, it was imposter syndrome. They were just rock stars. I don't know how they were doing it. Eventually, I had to accept it. It was time to level up. It was a difficult decision because it meant slowing down to learn something new and scary. But I embraced it full scale. TypeScript really is amazing, and I promise this is not a TypeScript talk, but maybe some little messaging. I started rewriting React Table version 8 two years ago with TypeScript, and I was like, I'm going to get a new version out in two weeks. It will be like an alpha. Two weeks, it will be easy. No way. I did not know what I was doing. I had jumped into the deep end, and I had learned that writing libraries and TypeScript, this is super advanced stuff. I didn't even know how to use TypeScript as an app developer yet, and I was trying to write a library. I was in over my head. So I put the bat signal out onto Twitter, and I had some awesome people come to my rescue, offered their time and all of their energy towards helping me learn TypeScript in all the various ways, like looking at their patterns, live calls with everybody, support through maintenance. This is my TypeScript team, and I just wanted to thank them publicly because they're awesome. But they all basically said the same thing. Yeah, thank you. Thanks. They all basically said the same thing, though. Hold on to your butts. Because library TypeScript is crazy. Oh, also, generics. They're going to rock your world. They're going to make you cry, and then they're going to make you so happy. They're so cool. In fact, let's talk about generics really quick. It's basically the process of taking something that would be typed statically, like a string, and giving your types variables so that you can pipe those types into your system and back out to your users. This is a really simple function. But you can also use multiple generics to extract information out of types and provide it back to the user in the form of auto-complete. Everybody loves that about VS Code, whether you're a TypeScript user or not. Library generics are on another level. Look at the create column function for React table. That's 10 generics. Okay, let's run that through prettier. Okay, that's actually what we're going to see, right? It's okay, we've got some options and a column. I don't know if anybody noticed, but we're not even doing the implementation yet. And this is how much code we have. Imagine, like, okay, there's at least 36 functions in React table, and they all consume about the same amount of generics. Does anybody know how many lines of code that is? That's like 5,000 lines of code. It's not even lines of code, it's lines of types. This was something that I had a hard time grasping with TypeScript, like, why am I doing this, right? Yeah, the implementation wasn't even done. So I was pretty sad, but I had this idea. Anybody else run into this situation with JavaScript? Like, holy cow, that's a lot of arguments. What do we do? You put it into an options bag. Boom, options bag, bagging it. So we can do the same thing with generics. We can take all these generics, pull them out into a generic type, and reuse it as a variable. This is something very new, and I haven't seen it a lot in the wild. I hope it pans out, because it's amazing. After making this change, I was able to access all of my generics like a can of JavaScript objects. It's called generic maps, and I don't know why it's called generic maps. I think it should be called generic bags. But I was able to reduce the source code of React table by, like, 70% by implementing this pattern. I'll probably have to talk more about this in a TypeScript talk. But this was the point where I started feeling confident. I was like, okay, I'm dangerous, and I know a little bit of generics. I'm feeling good. All the great things about TypeScript started coming out. All the refactoring, less bugs, better design. I was able to take all of the things that are normally just stuck in your brain that are going to fizzle away if you walk away for two weeks from your project, shove them into TypeScript, and just sleep at night, clearing dependency trees of my code. I think it's a necessity. There's so much more we need to talk about with TypeScript. I just can't do it. It's a winning technology. Take it from someone who was a full 180 from last year. You need to try it. You need to use it. Not a lot of time left, but there's one more thing I want to talk about that is a little bit of a battle story with React table, but it's also the future. I just want to reassure everybody right now. I promise I love React. I'm here to stay. But we would all be very naive to think that React is some superior species, and it's the only thing capable of producing amazing apps and UI. I know we love it, but we need to take it off the pedestal once in a while. There are other frameworks out there. Solid, Vue, Svelte. All right. Come on in. And you know, I think that they deserve tables as well. I think they deserve a great table that I could build in React. And in the time-honored tradition of pushing the limit at the last moment, I decided to take React table and go agnostic. So React table is now called TanStack table, and it's going to ship with all adapters for all the frameworks. Angular, yeah. You want to work on the Angular adapter? Come talk to me. But it's framework agnostic, and this normally would be very difficult, but apparently standing on the shoulders of headless UI makes it a lot easier. We're already separating out markup and styles, and that makes up a lot of the differences between a lot of our frameworks out of the gate. And it turns out we just needed a few adapters to sit in the middle, to set up the internals of Reactivity and context. This is the solid table adapter. That's it. And all the other adapters basically look exactly the same, even React. So the last five years have been really interesting with TanStack table. Two years of it devoted just to implementing and learning TypeScript. It was crazy. There's really only one thing left to do. Should we do it? All right, let's do it. Wait, wait. We're not even connected to Wi-Fi. I'll do it after the talk. It's okay. There's also some other things I want to talk about really quickly. So I'm going to talk about the Angular API. I'm going to talk about the Angular API and the Angular API. I'm going to talk about the Angular API and the Angular API. And I'm going to talk about the Angular API and the Angular API. There's also some other things I want to talk about really quick. Over the next 30 days, we're going to be converting over to TanStack Query, Virtual, and Ranger, and the rest of the libraries are coming soon. I wanted to really thank everybody who's helped out with these projects. Anybody virtual, there's a lot of maintainers and contributors working, especially in other frameworks, and I think that's really awesome. Also, all of my GitHub sponsors. I wouldn't have been able to do it without them. I've got one sponsor, it's brand new in particular, that you wouldn't expect, but AG Grid. Hmm. Normally TanStack Table, it's kind of weird saying that now, and AG Grid have been viewed as competitors. You know, it turns out that that's not really the case. They're so very different. They solve uniquely different problems with very different paradigms. Depending on your use case, you might want to use either one. Just like I, at one point, used AG Grid and loved it. We came to this realization, and we knew that it was time to work together. So, today I'm announcing that AG Grid is the first TanStack OSS partner with TanStack Table, and together we're going to work as hard as we can to educate everybody in the ecosystem, regardless of framework, how to build better tables, when to use each tool, and we're going to share as much knowledge as we can across this chasm and make sure that we can all be friends. You can read more about it on tanstack.com. That's it. Applause Applause Applause Applause Applause Applause Applause Well, thanks a lot Tanner. As a user of React Table, I used it in a previous project. It was really, what you said, shifting to the headless paradigm, it was a weird thing at first, but as soon as you get going with it, you're like, yeah, this is how it should be, right? I can tell everyone that thinks it's weird. It was basically the same thing for me when I saw React the first time. It feels weird, right? Writing your markup in JavaScript. It feels weird, but it feels so good when you start using it. It's the control you get. So, if you have any questions for Tanner, you can do so at slido.com. There's one question from Metin Persinski. Sounds like a nice guy. So, when you started learning TypeScript, how long did it take for you to accept it and not feel slowed down by it? For me, it was like six months before I felt, oh, I get this. Yeah, honestly, it's like a delayed release capsule that you take, right? The beginning, you're like, eh, I'm not really feeling the benefits. I feel like around two weeks, you start to see the light, and it just keeps accelerating up into six months marker. I'm still appreciating things I'm learning about TypeScript. Oh, for sure. And every day, there's new frustrations also. No overload matches this call. Who's been there? Painful, right? Not a clue how to solve it still. Like, three years in. Next question from Golub. What was the best aha moment in your React table journey? Headless UI. Easy. Yep. Cool. Covered. Next question from GN. How would you go about convincing your team to switch to TypeScript? I don't know. Go through a pair programming session of refactoring something across multiple files. That experience is a hundred times better with TypeScript. You can go and change one thing, and it literally tells you everywhere in your app that you need to go and update. You can't keep that all in your head. And even the auto-complete, that becomes a lot better. There's just so many benefits. Yeah. But we're not a TypeScript conference. And this wasn't a TypeScript talk. Maybe a bit. Next question. How did you stay sane doing open source work? That's not everything I do. I have a startup. It takes up a lot of my time, too. I lip a lot. If I can do one thing that benefits both of those, that's what I do. I have a family that distracts me enough so that I don't get too deep into doom-scrolling issues and everything. So, yeah. Yeah, just find distractions. So, that's it for the questions that we have. So, any questions you have, you have to ask them right now. Ah, one coming in. I imagine that it was easy for you to find help with TypeScript, given your contacts and public image. But how would other people that don't have your network get that benefit? First, just read through all the docs. The TypeScript documentation is amazing. And I realized later that everything that my friends were helping me learn, I probably could have learned on my own if I had just dug into the source code of open source libraries and just kind of started to put it together. Granted, I don't think a lot of people are going to need to learn that much advanced TypeScript unless you write a library of sorts. Like, most of the time, the documentation and the handbook is going to get you basically all the way there. What I like myself, which for me was an eye-opener when starting React, TypeScript, is that when there's an error, you get an error code. And you can copy-paste it into Google and boom. So, that was really easy for me. So, yeah. Just ts and some number and you'll find a Stack Overflow post explaining the same problem. Unless some type cannot be assigned to another type. Then there's just no help. That's painful. Well, that's all the time we have then for Q&A. If you want to continue the conversation with Tanner, you can do so at the speakers booth or on SpatialJet. Tanner, thanks a lot. Sorry for ruining Jurassic Park. You'll never watch it the same.
24 min
17 Jun, 2022

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Workshops on related topic