Migrating Legacy PHP to a TypeScript Stack: The Path Without a Big Bang

Roughly 38 percent of all PHP websites run without security patches. This guide shows IT leaders the path from legacy PHP to a TypeScript stack β€” without a big bang: decision criteria, five migration steps, and honest cost ranges.
8 min readMatthias RadscheitMatthias Radscheit
Happycodingen-US

TL;DR

Roughly 38 percent of all PHP websites run on versions without security patches. The way out does not require a big bang: first settle the fundamental question β€” Laravel upgrade or stack switch β€” then migrate with the strangler pattern: Next.js facade, API extraction, shared database, Keycloak as the auth bridge, module by module. First module from €8,000, parallel operation included.

  • Roughly 38% of all PHP websites run on EOL versions without security patches (W3Techs, July 2026) β€” in the maintained Packagist ecosystem it is just 11%: PHP legacy is a maintenance problem, not a language problem.
  • Before any stack switch comes the fundamental question: with an established PHP team and a viable Laravel path, staying is legitimate β€” though Laravel runs on a cadence of just 18 months of bug fixes per major version.
  • The path without a big bang: a Next.js facade in front of the legacy system, API extraction from the monolith, a shared database during the transition, Keycloak as the auth bridge, then module-by-module replacement.
  • Strangler projects fail roughly 40% less often than big-bang rewrites (Security Boulevard, 2026) β€” every cutover step stays individually testable and individually reversible.
  • Cost anchors: integration layer plus identity setup €5,000–20,000, first replaceable module €8,000–20,000, full modules with auth and roles €20,000–60,000.
  • Do not migrate when remaining lifespan is short, systems are stable with no pressure to change, or the application is purely a content website β€” there, securing beats replacing.

Nearly four in ten PHP websites no longer receive security patches: 29.7 percent still run on PHP 7, another 8.1 percent on PHP 5 (W3Techs, as of July 2026). If your application is among them, you are not managing a modernization topic for someday β€” you are running an unpatched system in production. And with PHP powering 70.6 percent of all websites with a known server-side language, that is not a niche problem; it is the norm across legacy portfolios. The good news: the way out does not require a big bang. This guide describes the path we take with mid-sized clients β€” module by module, with the business running.

Sorting out where you stand: three types of PHP legacy

Type 1: The aging custom PHP application. Built between 2008 and 2018, often by a vendor that no longer exists or whose key people have left. The version question comes first here: everything before PHP 8.2 is end-of-life. PHP 8.2 receives security fixes only until December 31, 2026, PHP 8.3 until the end of 2027 β€” since the policy change of March 2024, the rule is two years of active support plus two years of security-only fixes (endoflife.date, as of July 2026). A pure version upgrade is rarely trivial for these applications, because extensions and dependencies have to move along with it.

Type 2: The homegrown custom framework. An in-house build from the era before Composer, with its own routing, its own ORM, its own template engine. These systems are the most expensive to operate: every new developer first learns the framework, then the business domain. Upgrading them to modern PHP versions is effectively an in-house rewrite β€” which puts the question on the table whether that budget would not be better spent on a stack you can still hire for in 2030.

Type 3: The application that grew out of WordPress. Started as a marketing site, turned into a business application over years of plugins and custom code β€” customer accounts, order processes, integrations. The problem here is less PHP than the architecture: business logic lives in a CMS that was never designed for it, and every plugin update is a risk to the core business.

How concentrated the problem is becomes clear when you compare two data sources: in the actively maintained Composer/Packagist ecosystem, only 11 percent of installations run on EOL versions, with PHP 8.4 leading at 32 percent (stitcher.io, collected July 2026). Across all websites, W3Techs puts the figure at roughly 38 percent. The gap between those two numbers is the real diagnosis: PHP legacy is not a language problem but a maintenance problem β€” it concentrates in codebases nobody actively maintains anymore. And even the maintained ecosystem carries baggage: only 352 of the 1,000 most important Packagist packages require a minimum PHP version that still receives security updates (stitcher.io, July 2026).

The fundamental question first: modernize in PHP or switch stacks

Before anyone talks target architecture, a less comfortable question belongs on the table: does it have to be a stack switch at all? The obvious path is modernizing within the PHP ecosystem, typically toward Laravel. That path works β€” it just runs on a cadence you should know: each major version gets 18 months of bug fixes plus 24 months of security fixes. Laravel 13, released in March 2026, requires PHP 8.3 through 8.5 and receives bug fixes until September 2027; security support for Laravel 12 already ends in February 2027 (endoflife.date, as of July 2026). Staying does not buy you peace of mind β€” it buys you a permanent upgrade rhythm, one that a well-practiced team can manage perfectly well.

The case for switching stacks is structural: a TypeScript stack with Next.js and Node brings frontend and backend together in one language β€” one team, one type system, shared data contracts. According to State of JS 2025, 40 percent of respondents now write only TypeScript β€” a clear signal of where the web talent pool is heading. What matters, though, is not language fashion but your situation β€” and that comes down to five criteria.

CriterionModernize in PHP (Laravel path)Switch to TypeScript
Team situationEstablished PHP team in place, backfilling securedPHP expertise leaving, backfilling difficult
Frontend shareLow β€” server-side application, little UI pressureHigh β€” portals, self-service, app-like interfaces planned
Integration needsFew interfaces, closed systemMany APIs, third-party systems, headless requirements
Remaining lifespanUnder three years, or unclearFive years or more, application is core to the business
Rate of changeStable, few changes per yearContinuous development with a product roadmap

Our honest take: if the left column mostly applies, stay in PHP β€” a Laravel upgrade with an established team is the cheaper, lower-risk path, and no agency should sell you anything else. If the right column mostly applies, the switch pays off. How to pull it off without interrupting operations is the rest of this guide.

The path without a big bang: five steps

The classic mistake is the big-bang rewrite: develop in parallel for two years, then flip the switch on a set date. Incremental replacements following the strangler pattern fail roughly 40 percent less often than big-bang approaches (Security Boulevard, 2026). Documented PHP-to-Node migration guides likewise recommend endpoint-by-endpoint cutover behind a load balancer or reverse proxy (NextGen Digital Craft, February 2026). To be transparent: hard-numbered case studies are scarce for the PHP route β€” the pattern itself, however, is all the better established. Five steps have proven themselves in our projects.

Step 1: Put a Next.js frontend in front of the legacy system

The first building block is an integration layer: a Next.js frontend takes over the user interface and talks to the PHP estate behind the scenes. Users see a modern application from the first release, while the legacy system keeps doing the work in the background. We have described how this pattern works in detail in our guide Next.js as an integration layer for legacy systems. The effect matters politically, too: the project delivers visible progress before a single line of backend has been replaced.

Step 2: Extract APIs from the monolith

For the facade to work cleanly, the legacy system needs defined interfaces. In practice, that means exposing the relevant functions of the PHP monolith behind a thin API layer β€” read-only first, then writes. These contracts, typically an OpenAPI specification, later become the yardstick for every new module: the TypeScript successor must fulfill the same contract before traffic is rerouted. That keeps every cutover step individually testable and individually reversible.

Step 3: A transition phase with a shared database

The pragmatic β€” and often unspoken β€” part: during the transition phase, old and new systems access the same database. Architecturally, that is ugly; operationally, it is right, because it decouples data migration from module replacement. What matters is clear write ownership: every entity has exactly one writing owner, everyone else reads. The actual data migration follows later, module by module, once the new owner is in production.

Step 4: The auth bridge β€” one login for both worlds

Nothing destroys user acceptance faster than duplicate logins during a migration. A central identity solution like Keycloak sits in front of both systems: users sign in once, and old and new systems validate the same tokens. The side effect pays off twice: roles and permissions are modeled once, centrally β€” an investment every subsequent module reuses.

Step 5: Replace module by module β€” and eventually switch off

Now the actual replacement begins: the first module β€” well-bounded in business terms, under high pressure to change β€” is rebuilt in TypeScript and put into production behind the facade. The pattern then repeats, prioritized by business value. The principle matches the two-speed strategy we have described for Java core systems; for Spring Boot teams there is the analogous migration guide toward NestJS. The PHP system is never switched off in one act β€” it becomes irrelevant, until the last cron job has moved.

What it costs: the realistic ranges

Concrete numbers instead of evasive boilerplate β€” these are the ranges from our projects. They depend above all on the degree of integration and the data quality of the existing system:

Building blockTypical range (net)What it covers
Modernization assessmentFixed price after discoveryInventory, module boundaries, prioritization, target roadmap
Integration layer + identity setup€5,000–20,000Next.js facade, API contracts, Keycloak integration
First replaceable module (MVP size)€8,000–20,000Well-bounded business domain, live behind the facade
Full modules with auth and roles€20,000–60,000 per moduleComplex business logic, permissions, data migration
Continuous replacement on retainer€4,000–12,000/monthPredictable progress alongside day-to-day business

As of July 2026. All prices net of VAT. Ranges drawn from real happycoding.agency projects; figures become binding after the discovery phase.

When you should not migrate

You have an established PHP team and a viable Laravel path. Then staying is the economically better decision. A team that masters its framework and keeps up with the upgrade cadence beats any stack switch β€” a migration solves technology problems, not team problems.

The application has less than three years of life left. If the system will be replaced by standard software anyway or retired along with its business unit, securing it is enough: upgrade to a supported PHP version, hardening, and if necessary isolation behind a WAF and VPN. That is unspectacular β€” and exactly right.

The system is stable with no pressure to change. An internal tool that has run reliably for years and needs two changes per year does not justify a rebuild. The rule here: current PHP version, maintained dependencies, monitoring β€” nothing more.

Your application is, at its core, a content website. A WordPress site that primarily serves content is well served staying in WordPress. Things only get critical once business logic has grown into the CMS β€” then the problem is not PHP, but where the logic lives.

The next step: inventory before investment

The solid starting point is not a fundamental decision in the steering committee but a compact inventory: which modules does the monolith contain, where is the pressure to change, what depends on which PHP version, which module makes the best first candidate? That is exactly what our fixed-price modernization assessment delivers β€” you will find the details on our software modernization page. And if you want to clarify upfront whether your case looks more like a Laravel upgrade or a stack switch: a 30-minute intro call is enough for a first honest assessment.

Frequently asked questions

How long does a PHP-to-TypeScript migration take?
It depends on module count and degree of integration β€” reliable industry benchmarks barely exist for the PHP route. From our projects: the integration layer with a Next.js facade and identity setup stands within a few weeks, and the first replaced module goes live after a few months. Fully replacing a grown monolith usually takes years β€” deliberately in parallel with day-to-day business, which is precisely the strangler approach's advantage over a big bang.
Can we keep developing the PHP system during the migration?
Yes, within limits. Modules close to replacement should be frozen; everything else stays changeable. The API contracts between facade and legacy system keep changes controllable: as long as the contract stays stable, both sides may evolve. We consider a months-long feature freeze a project mistake β€” it creates political pressure that topples migrations.
What happens to our database?
During the transition phase, old and new systems use the same database with clear write ownership: every table has exactly one writing owner. The actual data migration follows module by module once the TypeScript successor is in production. That decouples the data risk from the replacement risk and avoids the risky cutover-day migration of all data at once.
Isn't a Laravel upgrade the cheaper alternative?
Often, yes β€” with an established PHP team, the Laravel path makes economic sense, and we say so openly. Factor in the cadence: 18 months of bug fixes plus 24 months of security fixes per major version (endoflife.date, 2026), which means regular upgrade projects. The stack switch pays off mainly with a high frontend share, heavy integration needs, and difficulty backfilling PHP roles.
What does getting started with the migration cost?
The modernization assessment runs at a fixed price after discovery. The integration layer with identity setup ranges from €5,000 to €20,000, and the first replaceable module at MVP size from €8,000 to €20,000. Full modules with auth and roles cost €20,000 to €60,000, and continuous replacement runs on a retainer starting at €4,000 per month. All prices are net.
Do we need an entirely new team for the new stack?
No. PHP developers who know modern frameworks find their footing in TypeScript and Node faster than commonly assumed β€” concepts like routing, ORMs, and dependency handling carry over. A realistic setup is a mix: external senior support for architecture and the first modules, with internal capability built up in parallel. According to State of JS 2025, 40 percent of respondents write only TypeScript β€” the talent pool is there.

Sources

Related articles

Open for select projects

Let's talk about your project

Book a no-obligation call, send us an email, or use the form – we'd love to hear from you.

150+
Completed projects
15
Years of experience
8
Senior‑level team members