Expertise

Legacy
modernisering.

Van oude code naar nieuwe mogelijkheden, zonder de tent plat te leggen. Bestaande systemen stap voor stap modern maken, met een werkende rollback op elke release.

Het werkt, en dat mag zo blijven.

Legacy-systemen krijgen een slechte pers, maar onderschat niet wat ze vertegenwoordigen: jaren van business-logic, rand-gevallen die in de code zijn geëvolueerd, en workflows die je team door en door kent. Een rewrite vanaf nul verliest al die onzichtbare kennis, en komt vervolgens met dezelfde edge-cases opnieuw in aanraking, nu zonder historisch geheugen.

Onze aanpak is omgekeerd. We behandelen de bestaande code met respect, documenteren wat er draait, en vervangen hem fase voor fase. Nieuwe componenten komen naast de oude te staan, nemen verantwoordelijkheden over totdat de oude module niet meer hoeft. Pas dan trekken we de stekker, en dat is een bewuste, geplande laatste stap, geen accident waiting to happen.

Wat je van ons krijgt: een draaiboek per migratie, een werkende rollback voor elke wijziging en een realistisch beeld van risico's voordat er code verandert. We zijn niet bang om te zeggen dat een bepaald onderdeel beter gerenoveerd dan vervangen kan worden. De oude PHP-klasse die al tien jaar correct factureert is meer waard dan een nieuwe versie die nog moet bewijzen dat ze het beter doet.

// wat_we_bouwen

Wat wij bieden

Van eerste assessment tot uitgefaseerd legacy-systeem.

Codebase-assessment

Twee weken met je code, je database en je team. Resultaat: een technisch rapport met afhankelijkheden, risico's, quick wins en een gefaseerd migratieplan met vaste scope per fase.

Strangler-fig migratie

Nieuwe code groeit naast de oude. Een routing-laag stuurt verzoeken per module door, oud of nieuw, afhankelijk van waar we staan. Business gaat door alsof er niets gebeurt.

Database-modernisering

Van MySQL 5 naar modern Postgres, van verweven schema naar modulair. Zero-downtime-migraties via dual-write en shadow-reads.

Feature flags en parallel-run

Per gebruiker, team of module switchbaar tussen oud en nieuw. Test in productie zonder iedereen te exposeren aan nieuwe code.

Blue-green deploys

Elke release heeft een werkende rollback. Fout in productie? Binnen seconden terug naar de vorige versie, zonder dataverlies.

Business-logic behouden

Voordat een module gemigreerd wordt, schrijven we tegen-tests tegen de bestaande flow. De nieuwe code moet dezelfde uitkomst leveren als de oude, bewezen, niet aangenomen. Edge-cases die jaren geleden in de code zijn geslopen, blijven meegaan.

// aanpak

Zo werken we

01

Assessment

Codeleesuren, database-analyse en gesprekken met je team. Waar zit de pijn, wat moet blijven, wat zou eigenlijk niemand missen?

02

Strategie

Strangler-fig, parallel-run of gefaseerde rewrite, per onderdeel passen we de aanpak aan. We leveren een fasering met risicoprofiel en vaste scope per blok.

03

Gefaseerde uitvoering

Eén module tegelijk, met een werkende rollback en contract-tests. Iedere release verkleint de oppervlakte van legacy, nooit andersom.

04

Sunset

Als niemand meer in de oude code werkt, trekken we gepland de stekker eruit. Code in read-only archief, database gearchiveerd, hosting opgezegd, netjes.

// stack

Waarmee we werken

Nieuwe stack én de expertise om bij je oude te duiken.

Van

  • PHP 5.6 / 7.x, plain of CodeIgniter
  • Symfony 2/3, Zend, CakePHP
  • jQuery-heavy frontends
  • MySQL 5.x en oudere Postgres
  • On-prem VPS en dedicated servers

Naar

  • Laravel (PHP 8.4) + Filament
  • Livewire, Vue of React per context
  • TypeScript, Vite, Tailwind
  • PostgreSQL 16+, Redis
  • AWS, Hetzner of Forge

Rondom de migratie

  • Rector voor PHP-upgrade-automatisering
  • Laravel Shift voor framework-bumps
  • Feature flags via eigen library
  • Terraform voor infra-as-code
  • GitHub Actions met staging-gate
// scenarios

Hoe dit er in de praktijk uitziet

PHP 5.6 / CodeIgniter naar Laravel 12

Een bedrijf draaide al twaalf jaar op een CodeIgniter-applicatie op PHP 5.6, end-of-life, maar volop in gebruik. Wij startten met een assessment, classificeerden modules op complexiteit en migratie-prioriteit, en bouwden de nieuwe Laravel-applicatie naast de bestaande op. Een reverse-proxy routeerde per URL oud of nieuw. Na elf maanden stond er een complete Laravel-stack, werd de oude codebase in read-only gezet en konden we end-of-life hosting uitfaseren. Nul dagen business-uitval.

Monolith met jQuery-spaghetti naar modulaire architectuur

Een SaaS-bedrijf had een volgroeide monolith met duizenden regels jQuery-JavaScript die niemand meer durfde aan te raken. Wij knipten de applicatie op in modules met duidelijke grenzen, vervingen de frontend per scherm door Livewire waar interactie genoeg was en Vue waar het intensiever werd. Feature-flags bepaalden per gebruiker welk scherm ze te zien kregen. Na negen maanden draaide de hele applicatie op de nieuwe architectuur, met aantoonbaar minder bugs en aanzienlijk snellere feature-deliveries.

On-premise naar cloud met zero downtime

Een organisatie wilde afscheid van een fysieke server in hun eigen datacenter, maar de applicatie draaide 24/7 productie. Wij zetten parallel de cloudinfrastructuur op (AWS, EU-regio, Terraform-beheerd), kopieerden de database met Postgres logical replication voor continue sync, en deden daarna een gecontroleerde DNS-switch in een onderhoudsvenster van vijftien minuten. Rollback-pad bleef drie weken open, bewezen werkend, voordat de oude server werd uitgeschakeld.

Veelgestelde vragen

Kunnen jullie onze oude PHP-applicatie migreren naar moderne Laravel?
Ja. We hebben PHP 5.6, PHP 7.x en zelfs CodeIgniter-applicaties begeleid naar moderne Laravel-versies. De aanpak is bijna nooit een rewrite, dat is te risicovol, maar een geleidelijke migratie waarbij de nieuwe applicatie naast de oude komt te staan en modules één voor één worden overgezet. Als de laatste module over is, kan de oude stack met pensioen.
Hoe voorkomen jullie dat er dingen breken tijdens de migratie?
Drie principes. Eén: we raken niets aan zonder een getest rollback-scenario voor die specifieke wijziging. Twee: elke release gaat via een blue-green of canary-deploy, zodat we binnen seconden terug kunnen als iets onverwachts opduikt. Drie: business-kritieke flows worden met contract-tests bewaakt, we weten dat de factuurregel correct berekent voordat de code live gaat, niet achteraf.
Moet alles in één keer over, of kan dat geleidelijk?
Geleidelijk, tenzij er een hele goede reden is voor het tegendeel. De strangler-fig aanpak (nieuwe code groeit rondom de oude en vervangt hem stuk voor stuk) is in verreweg de meeste gevallen de veiligste én goedkoopste route. Een big-bang migratie is alleen verantwoord als de oude applicatie zo klein is dat de risico's overzienbaar blijven.
Wat kost een complete modernisering ongeveer?
Dat varieert sterk met de omvang van de codebase, de staat van de database en hoeveel business-logic er ongedocumenteerd in zit. Een assessment van twee weken levert doorgaans een betrouwbare schatting op, compleet met fasering, risicoprofiel en vaste scope per fase. Kleinere trajecten beginnen met een Discovery van enkele weken; volledige moderniseringen van middelgrote applicaties lopen over meerdere fases verspreid over meerdere maanden.
Gaan onze gebruikers hier iets van merken?
In de ideale situatie merken ze pas wat bij de eerste nieuwe feature die in de oude applicatie niet mogelijk was. Tijdens de migratie zelf werken ze in de bestaande UI, onder de motorkap komt stukje bij beetje de nieuwe stack. Bij een UI-vervanging betrekken we eindgebruikers vroeg: we tonen prototypes, trainen key-users en draaien waar nodig een periode parallel met beide schermen beschikbaar.
Wat als er nog mensen zijn die in de oude applicatie werken?
Dat is het normale geval, niet de uitzondering. Daarom bouwen we migraties vaak als parallel-run: oude en nieuwe applicatie bestaan tegelijk en schrijven naar dezelfde database (of een gesynchroniseerde kopie) totdat iedereen over is. Per gebruiker, per team of per module switchen we de feature-flag om. Pas als niemand meer in het oude systeem werkt, trekken we de stekker eruit.
+ + + +

// volgende_stap.execute()

Oude code die blokkeert?

Vertel waar je vastloopt, we beginnen met een assessment en geven je een eerlijk beeld van de opties.