A Framework for Managing Technical Debt

Spanish audio is available in the player settings
Rate this content

Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt.

In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.

35 min
09 Mar, 2023


Sign in or register to post your comment.

Video Summary and Transcription

Today's Talk discusses the importance of managing technical debt through refactoring practices, prioritization, and planning. Successful refactoring requires establishing guidelines, maintaining an inventory, and implementing a process. Celebrating success and ensuring resilience are key to building a strong refactoring culture. Visibility, support, and transparent communication are crucial for addressing technical debt effectively. The team's responsibilities, operating style, and availability should be transparent to product managers.

Available in Español

1. Introduction to Refactoring and Technical Depth

Short description:

My name is Alex and I'm joining from Romania, from a city called Cluj. Today's topic is a framework for managing technical depth. I want to talk about refactoring culture and the three pillars of refactoring.

Hey everyone, thank you for chiming in for this session. My name is Alex and I'm joining from Romania, from a city called Cluj, which is in the beautiful heart of Transylvania, where I work as a frontend engineer at CodeSandbox and on the side, I'm also the founder of JS Heroes, our local community that organizes the local meetups here in Cluj and also the JS Heroes conference that happens every spring. You can also find me on Twitter at alexandmodovan and today's topic is a framework for managing technical depth.

And I wanted to talk about technical depth for a while and basically this talk is also not just about technical depth, which is inevitable for all the projects, for all the engineering teams, but also this is about refactoring. And I'm not necessarily going to talk with you about here's how you refactor code or here are some patterns for actually doing refactoring. I'm here to talk a bit more about the more meta layer, if you want, and I want to talk about refactoring culture, because I've been working for the past five to six years with different product teams, different engineering teams, vertical teams, horizontal teams, platform teams, and it always felt weird to me that we never really got refactoring right. As an industry we still have this problem a lot.

Actually, a few people talk about this in general, so I thought about exploring some things. Ever since I started thinking more about this, I started coming up with this framework, or structure, or more like, how do you build the right structure around the refactoring processes? This is what I refer to as a refactoring culture. The trigger for this particular talk came some good months ago. When we were working at Code Samples, we were working on this, let's say, small refactoring experiment where we introduced a new way of communicating with our backend. We have this backend of our code editor, which we call picture, which handles all the low-level primitives of what you can consider a code editor. Like file system access or tasks or processes and stuff like that. So we came up with this new way of doing it. And now we have basically two ways of doing the same thing in the application.

So we have a legacy picture provider, which was at the top of everything. And then inside it, we've got something called a picture provider. And just looking at this code at first, just looking at the PR that was kind of introducing this change, kind of at first made me scream, like, oh, no, this is not okay. We're just messing the code, we're going to live with this forever. And this is just kind of like a bad practice. But then I slowly started to understand it, actually this is okay, right? There was back then no possible way for us to just transition the entire codebase overnight, and just use the new way of consuming data. So we kind of had to support these two alternative ways. And this is what made me realize that, okay, as long as we have a method for this, as long as we have a clear understanding, you know, across the entire team that this is how we are handling this process, this is fine, right? This is more like managing this whole problem, now we have this technical debt, we are aware of it, but we are managing it at the same time. We're not, you know, stopping all development to just focus on this. We are moving forward with all our feature development. And at the same time, we have a plan to kind of mitigate this problem. So pretty much this is the, the gist of it, like what I want to kind of like say with this talk, like, okay, instead of fighting, you know, technical debt, instead of being in this process where whenever something pops up, whenever something is off, whenever, you know, the code base does not reflect the quality that we want it to be at, we stop all product development and we say to, you know, your product managers say, oh, we need to solve this because it's higher priority. That clearly ends up becoming a problem and a struggle for product development because you no longer have, you know, reliable way of just shipping like on a cycle basis. And at the same time, so instead of doing that, right, instead of saying, okay, I want to eradicate all technical debt as soon as it pops up, I'm thinking of a framework to more like manage this, right? To not be crippled by it, so you don't have to fall into the other extreme where, oh, we're not doing any refactoring anymore, we're just focusing on features and then just things just pile up, but at the same time not just be very reactive to this, like whenever something pops up, we immediately try to fix it. So this framework tries to put into place all these things, right? And this is what I call the three pillars of refactoring, because obviously there are three pillars, and we're going to walk through them in a bit.

2. Refactoring Practices and Inventory

Short description:

The first pillar is practices, which involves setting goals and guidelines for the team. It's important to document these practices and make decisions together. The next step is to assess the current state of the code base and identify the technical debt. This can be done by documenting the areas that need improvement and prioritizing tasks. For example, creating new components or deprecating outdated ones. It's crucial to have a separate document for tracking technical debt and not rely solely on the backlog. By doing this, you can build priorities and address the technical debt effectively.

So the first one, or the first thing you do is, or the first pillar is the practices. The next one is the inventory, and the third one is the process. Now, they might sound a bit abstract, but once I get through all of them, they will hopefully make sense for everyone.

So let's take them one at a time. What is practices about? Practices is pretty much about setting that goal with the team, sitting together and saying, in this team, in this engineering team, this is how we want to do things for this particular project, this is how we want to approach, this is the architecture, these are the patterns, these are the guidelines. So you have, again, all these things, patterns and all, we have your architecture.

Ideally, you have them documented as well, so a good practice of keeping track of these practices is to basically document them. You can have, you know, ways in which you want to structure your files and your folders, do you want to structure by functions, structure by feature, all these things, how you want to compose components, how you want to create components. Actually, at Code Sandbox, we do have this document for what we call the general coding guidelines. These are things that you don't, you can't really automate, right? There are decisions that just pop up. You can imagine you have a PR at some point and someone figures, hey, we've been doing this kind of logic, this is how we approach things for this kind of problem. Let's document this as a practice so that others can read it and come back later on, we can cross-reference it in other PRs and say, hey, we decided three months ago that we're going to name things like this or that we're going to use this particular abstraction like this or like if you have this, you should extract it in a separate component. All these things that cannot really be automated and are not always like black and white. They are more like, there are subtle differences and there are things that your team needs to decide on.

So practice is kind of setting this north star of where you want your architecture to be, where you want your patterns to be, what is the desired state in which the code base should be in or what's your aim as an engineering team? And then the next step is, in my mind is super important as the one that most of the things are, I think are missing, is kind of doing a bit of almost like introspection into the code base or research and figuring out what are we missing, right? What's the gap to this ideal or to this practices that we have in mind? This is what we want to get, but where are we now? Like, this is the inventory, trying to figure out what's missing, this is where you kind of document, what is your technical depth? You know, what are the parts of the application that need to be upgraded? You know, all the things that you need, all the steps that you need to do to get to that ideal scenario. So, you could have things in your backlog, for example, you start documenting, hey, we have specific tasks to upgrade something, to swap out an old way of doing things with the new way of doing things. Create a new component, extract a new component, deprecate a component, deprecate a system, whatever it is, you can have that somewhere documented. Some teams prefer the backlog. We did notice that backlogs are not the ideal scenarios for this because items tend to rot in the backlog, especially if you put them on low priority. So, we ended up with a separate document, for example, and I encourage everyone to kind of do this, try to figure out, okay, which are the key aspects of my code base that kind of have that growing technical depth. They can be very low, very small things, or it can be bigger things. In this case, we started documenting even the smaller things in this document called technical depth accounting. Whenever you introduce some technical depth or you guys just find something that all of a sudden, you're like, hey, this is technical depth that we haven't figured out, you document it somewhere. And it's not just living in someone's head that, hey, there's some technical document there. There is actually, it is actually documented in a place. And once you get to that, you start building priorities. And this is actually like a fun story. This is code from production that we still have. We had this Friday where we implemented something called the Markdown preview, basically taking Markdown files and rendering them nicely, formatting them for the preview when you navigate on the code base. And we kind of took this as a, it was almost like a hackathon experience where we just said, okay, let's build this.

3. Prioritizing and Planning for Technical Debt

Short description:

We had an idea and quickly built it, even though the code was messy. The component we created was not central to the application, so we could prioritize it accordingly. Planning for addressing technical debt is crucial, and it can be done through documentation and clear expectations. The process of addressing technical debt is similar to the process of developing a feature, with execution, ownership, and time considerations.

We have this idea, let's build it. And we shipped it in a couple of hours, a couple of engineers. And of course the code is awful and it's just a long list of callbacks and plugins on top of plugins and all sorts of weird quick configurations, but it just works.

And this particular part of the application, it's one particular component, but it's on the very edge of the architecture, right? It's not something that people will open on a daily basis to have to navigate through. It's not like a central, it's not a central experience, right? You can even disable it if you need to or it's very easy, just get that component out of that and all of a sudden markdown files do not have the preview option anymore.

So we started, when you start thinking about priorities, you have to understand, okay, there's no way I'm going to be able to address all the problems on this code base. So let's prioritize things. Is this important? Is this something that, is this a component, is this a system or a module that people access on a daily basis and have to deal with on a daily basis, then yes, let's put it with high priority and deal with it as fast as we can. If not, it can be very well a low priority thing or it can even be ignored. It can even not be on our radar. We shouldn't focus on this in our future process that we will talk about in a few minutes.

And finally, speaking also about inventory, you can also add here plans, right? Planning for what to do next. Like, how, okay, we have... Not only that we have discovered technical depth, we have documented it and we have prioritized it. But we can also say, okay, for this particular technical depth, the solution is do whatever, to replace the old component, the legacy component with the new component. To deprecate this use case, to extract some new subsystems or subcomponents from that. Planning like this can be done, I don't know, via RFCs or any sort of document that kind of explains these are the steps which we need to take to get from A to B, right?

Because coming back at these two first pillars that we talked about, you can pretty much imagine that your practices are kind of like the goal. I think I've already mentioned this, right? This is the aim that you have. This is where we need to go. This is what sets the expectations of the entire team that this is where we'll get with the code base. And the inventory is kind of giving you the harsh reality, if you want, right? This is where we are now. We're this far from our ideal practices. So with planning and with all the steps taken, right? With documents on both sides, with clear expectations and clear understanding and everything shared inside the team that this is, you know, this is our, this is how we proceed with this.

Then the process being the third pillar which we'll talk about in a second is kind of like the step of taking everything from the current state to the next state, right? Like almost like from A to B. And that's why in the plan is also part of the inventory because it will give you kind of the starting steps. Yeah, in order to address this particular technical depth, we need to do this, in order to, you know, move from the legacy system to the new system, we need to address this and that. So very important if you have these two prior steps, right? If you have done your research, if you have documented things, and if the team agrees on the ways to move forward, then the process kind of resembles a lot the process of any web development feature, right? Or any product feature for that matter. Like you have execution, right? You have ownership, someone gets assigned to a particular task. Okay, they need to change something, they need to fix a particular area of the code. Time is also taken into account because we have prioritized things, we have planned for solutions.

4. Steps for Successful Refactoring

Short description:

Mitigating technical debt requires following three key steps: establishing practices, maintaining an inventory, and implementing a process. Without these, refactoring efforts become unstable and disruptive to product development. Practices provide guidelines and goals, while an inventory helps identify areas for improvement. The process ensures that refactoring is executed with time considerations and team ownership. Two rules for successful refactoring are making tasks visible and creating a rewarding experience.

So we know, okay, mitigating this particular technical that might take a week, might take one hour, might take longer. It depends of course on the complexity of it. And you also have the progress, right? Every week since you've planned things out, since you work with a clear goal in mind, you can also pretty much figure out this is the progress, I'm halfway there, right? We still need time, or I'm almost done. So this brings, the process is kind of like very similar to any other feature. So it can be very much a product feature, it can be an engineering feature, or like an engineering task like this. You can see them through the same kind of lens here.

So just to recap, we have the practices on one end, we have the inventory, which gives us the gap where how far are we from this ideal scenario in which we want to get to, and then you have the process, which gets you from A to B. And it's very hard to do like a stable or a constant refactoring effort that doesn't disrupt product development if you don't really follow most of these things, right? Just think about it, if you don't have the practices in place, you don't really know where you're going, like you're just refactoring in vain, like, okay, I'm refactoring for the sake of it. You know, I just know that this is not okay, but I don't really know where to stop. Like when is enough, right? When is the quality of that code or of that architecture good enough for me? If you don't have the inventory, then you don't really know what to pick up. You start refactoring parts of your application. And again, the inventory is super important because it's often missed by teams. And you end up with someone picking up some task, wanting to refactor something, going through the entire code base, but missing chunks of like parts of the code that are not even taken into account because no one actually documented it. Hey, there are some problems there. We need to also address that. That's legacy as well, not just, you know, the main path that was refactored. And then of course, without the process, you can't really have anything if you don't take into account, you know, the time and the fact that the team needs to own this and whatnot.

So considering these steps, let's try in like in the last part of this talk, I'm going to try to give you a couple of examples of what I call the rules to make this work, right? Things that I noticed, like after thinking about this kind of process, like how this could work, I started seeing, okay, what are the things that, you know, teams are doing okay, or like the teams in which I worked were doing okay? That kind of helped this process move along, helped maintain these things long-term, as it made this more like a culture thing, more like an engineering culture thing rather than just another thing that is on someone's plate.

So rule number one is to make these things visible, right? You cannot really refactor in the dark. There is this common misconception that, you know, people just should refactor things on their own, right? Whenever they find something just quickly refactor it without the PM knowing about it because the focus is strictly on product development. You need to be very transparent about this, and I feel like everything should be in the open, right? There should be clear tasks for refactoring that are taken into account when you're doing cycle planning when you're doing iteration planning, when you kind of count for the amount of time that people will spend on the project and so on. There's nothing wrong with having that here in your project management tool in this case. This is how we do it at Code Sandbox. We also have PRs that are very clearly defined as refactoring PRs, right? We don't just slip some PR, some refactoring work into a feature PR because then of course you risk messing things up and you risk delaying the feature itself. So we try to separate. Whenever we find technical depth even is like high priority we need to immediately refactor this. We don't do that in that PR we just open another like a followup PR and we address that thing. And it's clearly marked as a PR for refactoring because then it gets reviewed differently, right? With different eyes you have different approaches for looking at code that is refactored rather than code that just adds something or fixes something that is, you know of more value to the product then to the code base. The second rule is to make it rewarding. Now it's very important that people get a sense of success from refactoring and from dealing with technical depth the same way as they do from shipping something, right? You get the, whenever you work on a product team whenever you ship something, you get a new release you get that, you know, that cool vibe that, hey, we shipped this, we made it, it's a success story.

5. Celebrating Success and Ensuring Resilience

Short description:

At Code Sandbox, we celebrate success by getting rid of unnecessary code and addressing common concerns. We have regular sessions to remove unused components and clean up the code base. It's important to prioritize product development but also keep track of technical debt and continue documenting and discussing future refactoring. The whole team needs to be involved and take ownership to make the process resilient.

So what we do at Code Sandbox, we also celebrate, you know any kind of success, which can be even like, okay we got rid of a ton of code on Friday. This is something that we recently I recently just embarked on. There's always, you have in our Slack channel there always, you know, on different code basis people are saying, hey, I just, you know refactor this whole thing. It felt very nice. We got rid of a bunch of things. We addressed some common concerns that we had in the past and now it's all gone and it's perfect. And we try to celebrate together with the team and we see it as a success.

Another way to celebrate, and actually like a fun thing that we do since the end of last year is we try to get rid of basically code that doesn't spark joy. And we call this the Marie Kondo of the code base. So we kind of gather in our, in our virtual office once every Friday or so. And we say, hey, we need to handle we need to handle these particular parts of like we have some code that exists for a while doesn't really bring a lot of value. We can remove it. Even if it's a small feature that maybe is forgotten somewhere. If we know that it's not used anymore we just get rid of it. If there are components that are unused if there are components that are not on the same level as other components in the design system, we try to just level and whatever we feel is kind of like we have that itch that yeah, this needs to go away. We need a better way to do this or we just need to drop this. Then we do it in these sessions. So we ended up documenting all of this again and keeping track. And every month we try to as much as possible spend time and just do this cleanup. Just get these out of the system get these out of the code base and keep technical depth and keep all these legacy things that at the end of the day to a minimum.

Last rule is a bit of a tough one is to make it resilient because the biggest threat to this to a successful refactoring culture is a culture in which feature development and product development always takes priority. And don't get me wrong like product development will always take higher priority and that's okay because that's what you need to do at the end of the day, that's the main task. It's just that when things get very intense when you don't have the time to actually do all these things you still need to make sure that the whole process is resilient. At least make sure that, okay, this month we won't have time to do any refactoring but we do keep track of technical debt. We still continue documenting things. We still continue discussing about the priorities about the future refactoring. We don't just let this slip because it's very easy for the process to just go to, okay, we don't deal with this now and we'll pick it up whenever. And that whenever can be at any time in the future. But what's important here is that to make it resilient you have to kind of have the buying of the whole team. And to have not just the buying but also the ownership of the whole team.

6. Building a Resilient Refactoring Culture

Short description:

To make our process resilient, we have regular meetings to address code base problems and document new tasks. When higher priority is given, we assign clear ownership and take actionable steps. Every team member can drive the refactoring culture and embrace it as a shared ownership model. Thank you and happy refactoring!

What we do here to make it resilient is we try to keep it in check. Whenever we go through a period of like more feature development, we still have these meetings and we do have these huddle meetings with the entire horizontal team, like working with front end even if we work in different product teams. And we get together and we say, hey, on this code base we still have this problem. We haven't had the time to do anything with it but this is the plan. We are pushing it forward. We have documented new things. Try to be in check. Try to get everyone in the team, be aware that this process is still there even if it's on like low priority for the time being.

And of course, when you do have the priority for that, make these meetings more actionable. Assign clear ownership. X can deal with updating some older tests. Y can add new components to the design system, standardize them because we use them in multiple places. There are tons of examples like these that you can do actionable things that you can do on a weekly basis. So these were kind of the rules and this is kind of the process that I have in mind and the framework that I have in mind for building these refactoring culture.

I do want to leave you with one quote that I adapted and that is that, every team has a person that drives this refactoring culture and if you don't know who that is, then it is probably you. I want to encourage everyone to fill in this gap if you feel like there's no one, you know, driving this effort, it takes a bit of effort that force to be the driver, but I'm pretty sure that using these things, using this very shared ownership model, you can convince everyone in the team that this is the right approach and then the team can start really embracing this as a culture thing, not just as something that one single person pushes. Thank you very much and happy refactoring. And I'm super glad to see Marie Kondo again in action and not taking her off stage or off desks. I see they're walking in the office. How are you doing today? I'm good, thank you. And thank you so much for having me. Let's go into the slide, the question that you prepare for us and see the results. How do you feel about it? Some, well, 46% of people said they have more than 20% time assigned and 37 between the 10 and 20% time. Of course, it seems like they are fluctuating a bit. So not yet, but the trend is there. It's quite interesting. Not really. I think it's overall, it's a positive result. I would say the fact that people do allocate time for this is a very good indicator that kind of the industry grows towards more, I don't know, sustainable software, everything feels a bit more organized. It feels like we've grown from that period of managers saying that you don't have to write tests.

7. Importance of Visibility and Support

Short description:

It's important to acknowledge the need for more time to keep things in check and ensure steady growth. Tools like formatters, linters, and CI pipelines can help maintain code quality, but manual processes are also necessary. Convincing product managers can be done with metrics, graphs, and demonstrating the impact on developer experience. Ownership and common concerns within the team are crucial. Risks and the impact on product should be communicated to gain visibility and support.

You just do a good enough job and then the code tests itself and then stuff like that. I think it's a positive indicator of people acknowledging that they do spend do need at least more time to keep things in check and to ensure that the code-based project and a piece of technology grows in a steady way.

Yeah, there is hope that not only shipping code is the way to go. Also taking care of the rest and how it integrates is a big important role.

We also have some questions from the audience and I'm gonna just go to them. And the first one would be, which tool are you using to go through this process or tools, if more? So, yeah, it's a good question. I guess if it's about specifically, specific tools that help you in these processes, unfortunately, it is a quite like a human-centric process because in my mind, okay, if you have tools, for example, for things that I talked about, like maintaining a certain level of code quality of coding guidelines. If there are things that can be automated then it's not even worth mentioning the process. Like you just have all the formatters, you have linters, you have CI pipelines that kind of validate everything and just keep things in check.

For everything that cannot be automated, it means that also there's not really a tool that can highlight things. You can start looking at things like code complexity, but I would say, always take that with a pinch of salt, make sure it's not like the, you don't just, you can have tools that help you, but you can never rely 100% on tools if there are things that cannot be fully automated. For example, we did rely on things like the node prune is one package that you can run on bigger code basis to just give you packages and modules that are unused, that sometimes some of those things are not easily spotted. So, there are some solutions out there, but unfortunately I would say the vast majority of processes that I talked about are kind of manual and require some sort of human ownership, so to say.

Indeed, indeed. And now that you mentioned human insight, Marie Kondo got appreciation. Ah, nice. People said that they loved that you call it the Marie Kondo method, but it seems that this person doesn't have necessarily issues to convince the business side that they need tech depth done. But in general, what would be your approach into convincing the product manager, the product owner that tech depth should be considered more and should be just not just brushed away?

Well, I think the classic, a classic answer for that is, you know, always, if you need, like if you don't have, you know, the ownership over that, if you need to convince someone, you probably will most likely convince them with some sort of numbers, graphs, like just the idea that hey, you know, six months ago or one year ago we were shipping features at this rate, now we're shipping at that rate, and like, this is a difference. And this is, you know, we clearly have a problem, you know, developer experience has been slowing down or things like that.

Yeah, I think I'm personally fortunate to have worked in the past years in an environment where I think everyone is kind of on board on this, so it's more like about the ownership. Like we more, most, it's more like about us having to take the ownership to doing the process rather than having to ask permission for it or something like that. But yeah, there's always, I think there are always metrics that you can pull from how fast people are delivering. You can also get just the, get the feeling of how the team feels about things. Just have a, if you're in a position to do that, have like a one-on-one with each engineer in the team and just have the common concerns voiced for everyone. So it's clear that it's got like a common front that the team does against this problem that's growing.

Yeah, István, what I was saying this is that I wanted to mention that sometimes it's also mentioning the risks and put yourself in the situation that the product owner, product person will see that something is going wrong because of this. And we literally got the question right now as it's big related to that. That isn't it irrelevant to product some of the certain refactoring tasks may take place a long while the feature development, meaning that we mentioned that we can decide and put this time but for product they could literally take off the table that. Why should it be distinct and visible to product teams?

So when I mean product teams, I mean, it should be visible to everyone that's concerned with them. So like, it's not like, you know, some engineer in the shadow does the refactoring and others just to prove it.

8. Transparent Communication and Availability

Short description:

At the end, it's important to be transparent about the team's responsibilities. Writing tests and non-coding tasks are also part of the job. The team's operating style may not be fully visible to the product manager, but they should be aware of it. Availability may be split between different tasks. Thank you for joining us today!

At the end, they say, hey, good ship it there. Let's just cover it somewhere. It's more about us being transparent that it's just part of the job. The same way as you know, writing tests is part of the job or anything from code review to any other non-coding task in a way is part of the job in the same way, I would say.

So it's not necessarily doesn't have to be visible to the product manager or product owner or fully transparent to them, but they should be aware that this is how the team operates. And also transparent with the availability of yourself. These few hours will be invested there. It's not that they're not doing product work for nothing. It's that my availability will be split between this.

Really, really insightful talk Alex. And I'm really glad that you shared all the insights and the processes you have established with this framework. Thanks so much for joining us today. Thank you. Thank you for having me. Bye. Bye. Thank you. Thank you for having me. Bye. Thank you for having me. Bye. Thank you for having me. Bye. Thank you for having me. Bye. Thank you for having me. Bye. Thank you for having me.

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

React Summit 2023React Summit 2023
24 min
Debugging JS
As developers, we spend much of our time debugging apps - often code we didn't even write. Sadly, few developers have ever been taught how to approach debugging - it's something most of us learn through painful experience.  The good news is you _can_ learn how to debug effectively, and there's several key techniques and tools you can use for debugging JS and React apps.
React Day Berlin 2022React Day Berlin 2022
29 min
Fighting Technical Debt With Continuous Refactoring
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt. In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.
React Summit 2023React Summit 2023
26 min
Principles for Scaling Frontend Application Development
After spending over a decade at Google, and now as the CTO of Vercel, Malte Ubl is no stranger to being responsible for a team’s software infrastructure. However, being in charge of defining how people write software, and in turn, building the infrastructure that they’re using to write said software, presents significant challenges. This presentation by Malte Ubl will uncover the guiding principles to leading a large software infrastructure.
React Advanced Conference 2022React Advanced Conference 2022
22 min
Monolith to Micro-Frontends
Top Content
Many companies worldwide are considering adopting Micro-Frontends to improve business agility and scale, however, there are many unknowns when it comes to what the migration path looks like in practice. In this talk, I will discuss the steps required to successfully migrate a monolithic React Application into a more modular decoupled frontend architecture.
React Advanced Conference 2023React Advanced Conference 2023
22 min
Power Fixing React Performance Woes
Next.js and other wrapping React frameworks provide great power in building larger applications. But with great power comes great performance responsibility - and if you don’t pay attention, it’s easy to add multiple seconds of loading penalty on all of your pages. Eek! Let’s walk through a case study of how a few hours of performance debugging improved both load and parse times for the Centered app by several hundred percent each. We’ll learn not just why those performance problems happen, but how to diagnose and fix them. Hooray, performance! ⚡️

Workshops on related topic

React Summit Remote Edition 2021React Summit Remote Edition 2021
87 min
Building a Shopify App with React & Node
Top Content
Shopify merchants have a diverse set of needs, and developers have a unique opportunity to meet those needs building apps. Building an app can be tough work but Shopify has created a set of tools and resources to help you build out a seamless app experience as quickly as possible. Get hands on experience building an embedded Shopify app using the Shopify App CLI, Polaris and Shopify App Bridge.We’ll show you how to create an app that accesses information from a development store and can run in your local environment.
JSNation 2022JSNation 2022
41 min
Build a chat room with Appwrite and React
API's/Backends are difficult and we need websockets. You will be using VS Code as your editor, Parcel.js, Chakra-ui, React, React Icons, and Appwrite. By the end of this workshop, you will have the knowledge to build a real-time app using Appwrite and zero API development. Follow along and you'll have an awesome chat app to show off!
GraphQL Galaxy 2021GraphQL Galaxy 2021
164 min
Hard GraphQL Problems at Shopify
At Shopify scale, we solve some pretty hard problems. In this workshop, five different speakers will outline some of the challenges we’ve faced, and how we’ve overcome them.

Table of contents:
1 - The infamous "N+1" problem: Jonathan Baker - Let's talk about what it is, why it is a problem, and how Shopify handles it at scale across several GraphQL APIs.
2 - Contextualizing GraphQL APIs: Alex Ackerman - How and why we decided to use directives. I’ll share what directives are, which directives are available out of the box, and how to create custom directives.
3 - Faster GraphQL queries for mobile clients: Theo Ben Hassen - As your mobile app grows, so will your GraphQL queries. In this talk, I will go over diverse strategies to make your queries faster and more effective.
4 - Building tomorrow’s product today: Greg MacWilliam - How Shopify adopts future features in today’s code.
5 - Managing large APIs effectively: Rebecca Friedman - We have thousands of developers at Shopify. Let’s take a look at how we’re ensuring the quality and consistency of our GraphQL APIs with so many contributors.
JSNation 2023JSNation 2023
57 min
0 To Auth In An Hour For Your JavaScript App
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.js backend + Vanilla JS frontend) to authenticate users with One Time Passwords (email) and OAuth, including:
- User authentication – Managing user interactions, returning session / refresh JWTs- Session management and validation – Storing the session securely for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
JSNation 2023JSNation 2023
87 min
Build a Collaborative Notion-Like Product in 2H
You have been tasked with creating a collaborative text editing feature within your company’s product. Something along the lines of Notion or Google Docs.
CK 5 is a feature-rich framework and ecosystem of ready-to-use features targeting a wide range of use cases. It offers a cloud infrastructure to support the real-time collaboration system needs. During this workshop, you will learn how to set up and integrate CK 5. We will go over the very basics of embedding the editor on a page, through configuration, to enabling real-time collaboration features. Key learnings: How to embed, set up, and configure CK 5 to best fit a document editing system supporting real-time collaboration.
Table of contents:- Introduction to the CK 5 ecosystem.- Introduction to a “Notion-like” project template.- Embedding CK 5 on a page.- Basic CK 5 configuration.- Tuning up CK 5 for a specific use case.- Enabling real-time editing features.