Legacy code modernization
Legacy code is almost never the actual problem. The problem is that nobody knows what it currently does. I work backwards from the running system: characterize behavior with tests, then change it deliberately, in small steps you can roll back.
Based in Groningen, working across the Netherlands and remotely for clients worldwide.
Refactoring and modernizing older codebases. Framework upgrades, careful test-driven changes, and migrations from end-of-life platforms.
Legacy code is rarely the original problem. The work is in understanding what behavior the current system actually has, then changing it without breaking the parts no one documented.
Good for
- Framework or runtime upgrades (Node, Python, Java, Rails, Delphi, and frameworks past EOL).
- Monoliths that need to be broken up without a full rewrite.
- Inherited codebases where the original team is gone.
How I approach it
- Pin down current behavior first. Before changing anything I capture how the system behaves today with characterization tests. Modernization must not quietly change what the business relies on.
- One piece at a time. Big-bang rewrites have a way of running long and shipping late, so I migrate one module, screen, or integration at a time, and the system keeps running throughout.
- Keep knowledge in-house. Along the way I document what the old system actually does, which is often written down nowhere. You end up less dependent on any one person, including me.
Work I can show
- go-catdoc. To read a 1990s document format from a modern Go service, I ported the catdoc C tool to run inside Go through WebAssembly, with no C toolchain needed at build time. View on GitHub.
- Delphi to the web. For a retail automation platform I fully replaced a Delphi application with a Go backend and a Svelte frontend.
Tech I work with
Characterization tests, contract tests, gradual TypeScript adoption, monorepo migrations, dependency upgrades, Delphi and Pascal modernization.
Frequently asked questions
Can you work with Delphi or Pascal codebases?
Yes. Modernization paths range from incremental refactoring within Delphi to full migrations to a modern web stack. The right path depends on how much business logic lives in the UI layer.
Will the application keep running during the migration?
Yes. Changes go in small, reversible steps with characterization tests added first, so the running system keeps its current behavior while pieces are replaced behind it.
What if there are no automated tests at all?
That's the common case. The first phase usually adds enough characterization tests around the parts we're about to change to make further work safe. Full test coverage is rarely the goal; safe-to-change is.
Should we rewrite or refactor?
Usually refactor, sometimes rewrite a component, rarely rewrite the whole system. The honest answer follows from the state of the code, the test coverage, and how long the current platform stays viable, which is exactly what a short audit establishes.
Want to talk it through?
Tell me what you're trying to do. I'll let you know honestly whether I'm a good fit.
Get in touchOther services
- Custom application development End-to-end design and implementation of bespoke applications across web, native iOS, and backend systems, including MVP builds for early-stage products.
- Web, API and backend development Production websites, web apps, and APIs in React, Preact, Svelte, and vanilla web. Backends in Go and Python with REST or event-driven APIs.
- AI and LLM integration LLM-powered features for existing apps and new products: agent workflows, RAG pipelines, and integrations with OpenAI, Anthropic, and similar providers.
- Native iOS apps Native iPhone and iPad apps in Swift and SwiftUI, including widgets, Live Activities, and App Store delivery.
- Browser extensions and integrations Chrome extensions, Thunderbird add-ons, and integrations between browsers and external services.
- Point-of-sale and retail software Custom POS systems, inventory and stock management tooling, and integrations with receipt printers and other store hardware.
- Performance-critical engineering Algorithms, audio and video processing, codec work, P2P networking, and other engineering-depth projects where performance and correctness matter.