I started Shift over 10 years ago. In that time, it's upgraded over 170,000 Laravel applications. To some, Shift may appear like magic - fully upgrading your Laravel application in seconds. Of course, it's not magic. But how does Shift work? Does it use Laravel? What's the architecture? Is it using AI? I'll answer all of that in this article.
Just PHP
There are two sides to Shift. There's laravelshift.com, which is the e-commerce site built in Laravel. Then there's what I call the engine - Shift itself. The code which performs the automated steps to upgrade your Laravel application and submit a PR. That is not built with Laravel. It's just plain old PHP. No framework. Only a handful of dependencies.
However, its architecture will still feel familiar to Laravel developers. There are facades. There are collection pipelines. There is a testing harness. All the wonderful affordances in Laravel that improve the developer experience are applied within the Shift codebase.
At its core, there's a Shift facade. It encapsulates all shared behavior: reading and writing files, making commits, scanning the code. So instead of multiple facades like File, Process, or Cache, it's a single facade. Think of it more like Carbon. Everything in one class. Easy to change. Easy to use. Easy to test.
Shift also leans heavily on Unix system commands - things like find, grep, and diff. It has a few custom shell scripts, inline Perl commands, and even a file I/O script written in Go. As always, PHP is the glue that binds them all together. It handles the interprocess communication and performs the actions. In addition, PHP parses your code. Normally using nikic/php-Parser, but also good old token_get_all.
The tools used reflect my preference for the simplest solution. I'm familiar with PHP - so I started there. But I don't need PHP to scan files; I can just use grep. I don't need a package to interact with the GitHub API; I can just use git. There's a Go script that's faster for file I/O - so I use it.
Just tasks
Digging a little deeper into the code, each Shift has its own class - a sort of registry. It encapsulates the Shift name, resource paths, version number, and tasks. The tasks are what drive the automation.
When you run a Shift, its tasks are loaded and performed in order. Each task focuses on a specific change - updating core files, bumping dependencies, adopting a new convention. Most tasks are completely self-contained. They read the codebase, make their changes, and exit cleanly.
These tasks often map directly to the atomic commits you see in your pull request, so you get a clear idea of how the work is broken up.
Isolating tasks makes them composable. Much like Unix commands, they may be combined to perform more complex operations or shared between Shifts. A few years ago, I created the Shift Workbench. This allows you to run your own set of tasks - essentially creating your own Shift.
Just ship
The mantra of just ship has spread throughout the Laravel community. I'm a big fan, but I may interpret it a bit differently. It's not just about building - it's also about releasing. Launching something for use.
On the surface, Shift is an ambitious project. Had I set the bar at upgrading 100% of applications with 100% accuracy, I would have never shipped. I had to accept that Shift would never be perfect. Given the dynamic nature of PHP and Laravel, there are too many ways applications can be written. I established a benchmark: take a conventional Laravel application from one version to the next and make it look like it had always been running that version. When I felt it did that, I launched.
Again, it wasn't perfect. I remember very early on getting feedback from Jeffrey Way. He said Shift was, "buggy". Adam Wathan felt it only handled about 40% of the changes, but he really liked the PR comments. At the time, this felt like failure. But it was critical feedback that shaped Shift's future - and likely its success.
Over the last 10 years, I've personally reviewed every single support email. Every one. It's been the most valuable source of input. When someone emails, "Shift didn't do X," I consider it a contribution. Not criticism. I reply, gather more context, add a test case, and push a patch. All those micro-improvements have made Shift what it is today. It's steadily moved closer to that 100% mark.
In that sense, Shift is a form of collective intelligence. Not AI in the LLM sense, but intelligence that accumulates from thousands of real codebases and developer feedback. It gets smarter with every run, every piece of feedback. Like AI, it's never 100% for everyone - but it might be 100% for most. And I think that's good enough.
Interestingly, what I once thought was a weakness has become a strength. Developers have grown to appreciate the reliability and interaction. They understand Shift isn't magic. Isn't AI. They can get the same result everytime they run Shift. They can send an email and get a response from the person who built Shift. That's helped grow a small community within the broader Laravel ecosystem - and I think both are stronger for it.
So, how does Shift work? Here's the short answer: it's a pipeline of focused tasks, built with plain PHP and Unix commands, improved by thousands of real-world codebases, and maintained with the patience to make it 1% better over time.