Laravel 9 to 12 in Two Weeks: the Part That Was Not the AI
Two weeks.
That is how long it took to move a large production codebase from Laravel 9 to Laravel 12 (three major versions) with delivery still running the whole time. When people hear the number they ask which model we used, which is the least useful question to ask.
The duration is a result. What you want is the order of operations, because that is the part you can copy.
The mistake is the one that feels efficient
You point an agent at the repository, tell it to upgrade to 12, and go and do something else.
It will work. It will produce an enormous volume of plausible change across hundreds of files, but you will have no way to tell which parts are correct. The only person who could review a diff that size at that speed is what actually wrote it. You have not upgraded a framework. You have swapped a codebase you understood poorly for one nobody has ever read, which is the same failure mode as code nobody can change, arriving faster and with better formatting.
An old codebase remembers decisions nobody wrote down. That is what an agent walks straight past.
Build the system of what needs to be done, first
Before a single file changes, you want a written plan that says what happens in what order and how you will know each step worked. Building that plan is intellectual work, and it is the step that gets skipped because it produces no visible progress. Everything below assumes it exists.
1. Map the system before you touch it
You need the architecture as it really is rather than as documented: what depends on what, where the business logic really lives, which directories are dead, and which files everything reaches into. Tooling that reports code smells and structure gets you most of it, and a caller map like OBY gets you the rest. That matters because the blast radius of a change is what you are managing for the whole job.
2. Extract the naming conventions before writing anything new
Old codebases have conventions, including bad ones, and they are usually consistent enough to describe. Write them down first. Every file that gets rewritten afterwards matches the house style instead of the model’s, which keeps the diff readable and keeps a reviewer’s attention on behaviour rather than on cosmetic churn.
3. Vendors and packages, from the outside in
Dependencies move first, working inward toward your own code. A framework major version is mostly a negotiation with everything you did not write, and doing this first turns a large ambiguous upgrade into a sequence of small ones with clear failure messages. It also surfaces the packages that are abandoned, which is a decision you want early rather than at the end.
4. Smallest files upward
On a codebase this size, 500 lines counts as a small file. Start with those. Work upward, leaving the 2,000 to 5,000 line files until last, by which point the conventions are established, the tests exist around them, and the model has hundreds of examples of how this codebase does things. Doing it in the other direction means making your hardest decisions with the least context available.
5. Keep the original beside the change
A copy of the file before it is refactored, kept where it can be read next to the new one. Version control has this, and people still do not open it mid-task. Being able to see both versions side by side is what makes a review take minutes instead of an afternoon.
6. Unit tests per core logic area, before the logic moves
Not full coverage, which you will not get and do not need. Tests around each area of core logic, written while the old behaviour is still the current behaviour, so they encode what the system does today rather than what the upgraded version happens to do. This is the only part of the process that tells you the migration preserved meaning rather than syntax.
7. Visual regression for the front end
Snapshot the interface, make the change, snapshot again, compare. That loop is what lets a whole front end move, including changes as large as swapping the styling framework, without a person clicking through every screen after every commit. It is also how you catch the class of breakage that no test suite notices and every client does.
Where AI earned the fortnight, and where it fought
It is very good at mechanical, repetitive and well-specified change. Renaming across hundreds of call sites, applying a new signature everywhere, rewriting a pattern the framework deprecated: that work is enormous, boring, and exactly what you want handed over.
It fights you wherever the old code encodes a business rule nobody documented. A conditional that looks redundant is load-bearing for one customer’s edge case from 2019. The model has no way to know that, will happily simplify it, and the simplification will be defensible in review and wrong in production. Those are the places a person has to slow down and ask what this was for, which is why the map in step 1 pays for itself.
The linting dividend
Here is a smaller point that changes the economics more than it should.
With a model doing the fixing you can run linting rules strict enough that a human team would refuse to live with them. Every rule that would normally be turned off after a fortnight of nagging stays on. The model being nagged does not get bored, does not get demoralised, and does not quietly add an ignore comment to make the noise stop. The quality floor of the finished code ends up higher than the codebase has ever had, on work that was only ever budgeted as an upgrade.
What this does not mean for your migration
The two weeks it took with the codebase for this article, with this plan, was driven by a lead developer who understood the domain.
A codebase with no tests and undocumented business rules takes longer, because step 6 becomes archaeology before it becomes engineering. A codebase whose dependencies are abandoned takes longer, because step 3 turns into replacement rather than upgrade. Anyone quoting you a fortnight before reading your repository is quoting the story rather than your system.
The honest general claim is narrower and more useful: the duration of a major-version migration is set by how well you understand the system before you start, not by how fast the tool writes. That ratio is what moved.
So the question worth sitting with is not how quickly we did it. It is how many of those seven steps you had in place the last time somebody told you an upgrade would take a quarter, and whether the quarter went on the upgrade or on finding out what the code did.
We do framework and platform modernisation on systems that cannot stop functioning while the upgrade project is happening, scoped to the codebase rather than to a calendar. If you want the map before you commit to anything, a code review gives you the dependency and risk picture first, and taking AI-assisted code to production covers the other direction.
Get in touch or call 1300 840 340.




