"Refactoring". Arguably one of the most, if not the most scary words for a lot of developers. But why? And should you be scared of it, too?
First of all, what is "refactoring"? According to Wikipedia, "code refactoring" is restructuring of the existing computer code, without changing its external behavior. As the simplest example, if you decide to rename some kind of variable in your code, without touching anything else - you are already refactoring that code. Does not sound that scary, right?
Of course, there are more complex examples, which will involve way more work, than search and replace. And that's where the fear comes from. Or rather it comes from the wrong reasons of doing the refactoring in the first place. A very good "controversial" example of a reason to refactor the code is migration from PHP to Node.js, and endeavors triggered by the desire to do something like this are what gives "refactoring" a bad name.
Not to bash Node.js, but the technology in itself does not provide much benefits over PHP. Yes, it can work better in some scenarios, but it may perform a bit worse in others. And in both cases you may require some specific module or plugin to introduce certain functionality that your project needs. Your decision to change the underlying programming language should not be based on just the convenience of maintaining the codebase. In this example, you should at least consider the level of interactivity, that you provide, because due to how Node.js works, it may be more suitable website with high interactivity in mind, while PHP may require some additional tinkering to introduce proper asynchronous processing, that becomes almost mandatory in such use case. If that's your use case - it may be totally valid to switch.
But if you want to replace a programming language just for the sake of replacing it... Not so much. Unfortunately it is quite common, when a developer joins a team and sees, that some part of a project is done in language X, which they do not know or do not like, and they say: "Let's switch it to language Y: I know it way better and consider it superior". This is a really bad reason to invest into refactoring, because it's not really factual, but this is exactly what happens a lot of the time, and why devs fear the concept. Because, you get to put in a lot of effort into something, that you do not really want to do, because you will not get anything out of it. Nor as a developer, nor as a company.
But that has a downside, too: you get locked into how things are done in the particular version of a framework, and you start using it everywhere, for any module of your big project. And then the developers of the framework decide to change something in the paradigm, that they use and you get forced into refactoring your whole codebase in order to fit it into the new paradigm. That is you get a sudden refactoring need, which can easily screw up your project's schedule. I've read a lot of articles and posts about pains of moving from one major version of a framework to another.
Not to say that it does not happen with new revisions of a programming language. For example, PHP 8.2 deprecated some ways to access callables, which may not affect everyone, but it can affect some. And the same thing can happen in libraries, that you are using, as well. But there is some difference compared to frameworks.
Programming languages, or more specifically, "general-purpose programming languages", are normally built in a highly modular fashion, meaning that a change done in 1 module, usually does not affect the other modules, at all. For the person doing refactoring, it means, that changes will need to be applied to a very limited scope, that is only to parts of the codebase, that use that particular changed module. And with libraries... Well, they are already "modules", so normally, they are used for a limited number of uses-cases, so, again, the scope of changes should be limited.
With frameworks... It all depends on the structure of the framework and the mindset (of framework) that is forces on the developer. Quite often frameworks use so many multipurpose abstracts, that a change in 1 of them triggers changes in behavior of other modules. As a developer on that framework, it is highly likely that you will not know for sure, if a certain seemingly small change will not blow up the scope of refactoring to your whole project. Yes, you can trust the changelog from framework's devs, but... What if they failed to test some very niche use-case, that is part of your project?
Hence the fear of refactoring. Often seemed as a useless effort or something sudden with unclear scope. And those are definitely the cases, that you need to avoid. Probably, have a talk with your project manager or lead, to prepare strategy for that.
But there are also good reasons to do refactoring, maybe even periodically, if resources allow that. Here are some examples, based on my own experience. Although, I may be wrong to an extent, since I picked up coding as part of "necessity" to implement my own ideas, instead of being "taught".
The website you are using right now started as result of me refactoring my codebase (and overall structure) in order to utilize an IDE (PHPStorm). Previously I used Windows' notepad and then EditPad Pro, which has syntax highlighting. I learnt about a free license for open-source developers for JetBrains' products, and got one. But I could not use my old codebase "as is". Well, I could, but it would not have leveraged all the power of an IDE. Thus I had to do some refactoring. I started using classes more, had some abstracts implemented, started using inheritance, started following (or at least trying to) PSR-4 for the structure... It took time and effort, for sure, but it still paying up the dividends, through easier coding and generally following good practices a bit more.
I also had a case, when I changed an HTML parsing library, that used DOM traversal to a regex-library, because regex was working way faster. It did not turn out as maintainable, in the long run, and I am considering of finding a middle ground between the 2 in the future, but it certainly improved performance of the scripts running at my backend.
I also had quite a few smaller refactorings, when I was introducing some new feature, too. Could I live without them? Probably. But at the same time thanks to these efforts, my code becomes more and more robust and it's common for me to have no errors on PROD server for months. Like no errors at all. Yes, when I push something new, sometimes I do get a couple of errors, usually with some edge cases, that I did not think about, but at those times I am prepared. Having confidence that my current codebase is capable of stable work is a huge thing.
And, honestly, I do not think I would have that confidence, if I did not do those refactorings in the past. Because, directly or not, I was improving, what I had. That is a very good reason to refactor your code, and to not be afraid of the process. Not the maintainability of the codebase, but the robustness and performance of the product.
All that's left is to time it right. But, unless you are like me, you will probably have a project/product manager to help with that.