“Can we rename this?”
Why does one innocuous question make every developer sweat?
It usually comes at the end of a good meeting. The demo went well. People nodded. Timelines were updated, next steps recorded. And then someone – a manager, a client, a stakeholder – says it:
Hey, can we rename this from X to Y? Everything else is great.
It’s a reasonable request. It’s a word. Words are easy to change. They’ve seen you change words on a screen before. There are probably a host of good reasons for it too.
They have no idea.
Years ago, while working on the Concrete CMS (then concrete5) ecommerce add-on, Franz asked me to rename it from “Core Commerce” (which we learned was already taken by a competitor in the space) to just “eCommerce for concrete5”. A simple request, right?
A name is never just a name
In a modern PHP and JavaScript app, its name is everywhere. Say the thing is called “Project” and it needs to be called “Workspace.” Here’s a partial list of where “Project” probably lives:
- PHP namespaces and class names:
App\Project\ProjectRepository - Directory names, which PSR-4 autoloading cares about very much
- Database tables and columns:
projects,project_id, foreign keys, indexes - Migrations, which are history, and you’re not supposed to edit history
- Routes and URLs:
/projects/42/settings - Config keys, environment variables, cache keys, queue names
- Event names:
project.created,ProjectWasArchived - JSON payloads in your API, and anything that consumes them
- JavaScript components:
ProjectList.vue,useProject(),projectStore - CSS classes:
.project-card,.project-card__header - Translation strings, tests, fixtures, factories, seeders
- Git repositories
And that’s one word in its singular, plural, camelCase, PascalCase, snake_case, kebab-case and SHOUTING_CASE forms.
grep -rniE "project" src/ resources/ tests/ | wc -lEvery fiber of your being wants it gone
Here’s the thing: developers hate a mismatch. Maybe it’s a particular quirk of my personality, but I find it very irritating to be confronted with something like this daily. It’s like a small lie that lives in the codebase forever. It’s just another example of me cutting a corner, even if the reason for doing so was completely understandable.
Every new developer will ask about it. Somebody will eventually write $workspace = $projectRepository->find($id) and feel a little bit worse about themselves.
So I completely understand the instinct to excise the old name completely. It’s the same instinct that prods us to build beautiful abstractions when it’d be quicker and easier to slap something together that does just exactly that one thing. We’re future-proofing.
So you start on your merry journey of renaming, and very quickly the other part of your brain shows up, the part that has done this before, and points out that nobody asked you to rewrite the app. They asked you to change a word on a screen.
So you compromise. You hold your nose, keep the code referring to the original name in non-public aspects like PHP namespaces and classes, and you change the public aspects of the name. Maybe you change the URLs too, with redirects from the old ones, because people bookmark things and URLs are kind of user-facing.
Everything under that stays “Project.” You write a short note in the README explaining that a Project is a Workspace, and you go to lunch. It’s not satisfying. But it’s correct, most of the time.
If you’ve shipped, you’re probably stuck
Why is it correct to take the easy way out? Because it’s actually the sensible path as well. Once an app is live and has extension points, the internal name stops belonging to you. It belongs to everybody who built on top of it.
Somebody out there has a class that extends your ProjectRepository. Somebody’s listening for project.created. Somebody has a script hitting /api/projects every night at 2am and has forgotten it exists. Rename any of that and you break them, and they won’t find out until it’s broken.
If you haven’t shipped, it’s actually worse
If the app isn’t live yet, nothing is stopping you. No add-ons. No API consumers. No backwards compatibility. You technically can rename every namespace, directory, component, method and comment. I’ve done it.
There’s no excuse. The pragmatic argument falls apart. “We can’t, it’d break things” turns into “we could, I just don’t want to,” and that’s a much harder thing to say out loud in a meeting.
And you really, really don’t want to. Because the work is tedious, and boring, and touches every file, and it’ll make every open branch conflict with everything. You’ll be fixing tests you didn’t need to break.
How did we ever do this?
I honestly don’t know how we did this before LLMs.
I dimly remember doing it in BBEdit. Multi-file search and replace across the whole project. Hundreds of windows open. Clicking through changes, then eventually not really reading them anymore, then just blindly accepting all of them because it was 11pm and the tests (if there were tests) would sort it out.
They did not sort it out. Search and replace doesn’t know that “project” in // TODO: clean this up before the project ships means something else. It doesn’t know that projects in a migration from three years ago should stay exactly as it is. It doesn’t handle Projects becoming Workspaces while projectile stays projectile. Fun fact: it will happily turn your projectile into workspaceile.
Using an IDE did help. A good rename in PhpStorm handles PHP symbols well. But it gets very difficul when you get into the details, like Twig templates, Vue components, string event names, SQL, config. This was always a tedious, manual process.
Until Now
The difference, as far as I can tell, is that an agent can do the boring version of the job carefully. It can tell a class name from a comment from a historical migration. It can rename the file, the import, the test and the factory together. It can run the tests and fix what it broke. It also doesn’t get tired, and it doesn’t seem to have any concept of whether a job is dispiriting or not.
It doesn’t remove the judgment. You still have to decide what changes and what doesn’t: do you rename the table, or just the model? Do old migrations stay untouched? Do you keep redirects for URLs nobody’s seen yet? But the painful, tedious hours or days of work can now be completed in minutes, in a way that leaves my mind free to contemplate big challenges. In the past I’d be wiped out, and also frustrated that all that work just led me back to where I’d been in the first place.
Hold on Loosely
I actually find this fairly freeing in a more existential way. In the past, a lot of my mind obsessed over the details of planning an architecture. I knew that if I didn’t get it right, it’d be a lot of work to undo decisions in the future. Yes, this is about naming a product, but it could easily be about any decision in programming. I’d want to get it right out of the gate so I didn’t have to undo my own work.
Now I don’t have to. If the name turns out to be wrong, or the database schema, or even fundamental aspects of the design, undoing it doesn’t cost me a week and my will to live. So I can make the decision that’s good enough today, ship it, and let the people using it tell me what the right answer was. I still care about getting it right. I just don’t have to get it right first.
