DEV Community

Cover image for Building Frankenstein Laboratory: Automating Legacy PHP Migration with Kiro IDE
Mongoo (Mungunshagai Tum)
Mongoo (Mungunshagai Tum)

Posted on

Building Frankenstein Laboratory: Automating Legacy PHP Migration with Kiro IDE

The Problem That Haunts Japanese Companies

After two years working at a traditional Japanese company, I've witnessed a crisis that affects countless organizations across Japan: legacy PHP projects that refuse to die.

Every year, teams struggle with migration projects. Some critical systems still run on PHP 5 - a version that reached end-of-life in 2018. Developers spend months manually rewriting code, risking bugs with every line. Business stakeholders grow frustrated as new features take a backseat to maintenance. Technical debt compounds year after year.

This isn't just my company's problem - it's an industry-wide crisis. Japanese companies, known for their stability and long-term thinking, often maintain systems for decades. But that stability becomes a prison when the technology underneath becomes obsolete.

During the Kiro Halloween Hackathon, I decided to tackle this head-on. The result? Frankenstein Laboratory - a tool that brings dead PHP code back to life by automating migration to modern Python.

What I Built: Two Projects in One

The solution has two components:

1. PHP Migration Tool

A web application that automates PHP-to-Python migration:

  • Clone any GitHub repository
  • Analyze PHP code structure automatically
  • Generate production-ready Python/FastAPI code
  • Create OpenAPI specifications
  • Generate property-based tests
  • Download everything as a deployable package

2. Strangler Studio Demo

A working reference implementation of the Strangler Fig pattern:

  • Legacy PHP application (student request system)
  • Modern Python API (FastAPI equivalent)
  • Nginx gateway for intelligent routing
  • Zero-downtime incremental migration
  • Comprehensive test suite

The Technical Architecture

Migration Tool Stack

Frontend (React + Vite):

// Four-stage wizard interface
const stages = [
  'Source',    // GitHub URL or ZIP upload
  'Analyze',   // PHP code analysis
  'Transform', // Python code generation
  'Extract'    // Download generated code
];
Enter fullscreen mode Exit fullscreen mode

The UI features a Frankenstein laboratory theme with animated logo, electric effects, and cinematic design. Six simultaneous CSS animations create a living, breathing interface:

.frankenstein-logo {
  animation: 
    float-logo 6s ease-in-out infinite,
    glow-pulse-logo 3s ease-in-out infinite,
    electric-spark 8s ease-in-out infinite;
}
Enter fullscreen mode Exit fullscreen mode

Backend (FastAPI + Python):

The backend handles the heavy lifting:

@app.post("/api/clone-github")
async def clone_github_repo(request: GitHubRepoRequest):
    """Clone and analyze GitHub repository"""
    # Shallow clone for performance
    git.Repo.clone_from(
        repo_url,
        extract_dir,
        branch=request.branch,
        depth=1,  # Only latest commit
        single_branch=True
    )

    # Analyze PHP code
    analyzer = PHPAnalyzer()
    analysis = analyzer.analyze_directory(extract_dir)

    return {
        "routes": analysis['routes'],
        "models": analysis['models'],
        "dependencies": analysis['dependencies']
    }
Enter fullscreen mode Exit fullscreen mode

The analyzer uses AST parsing to understand PHP code structure, identifying:

  • Routes and controllers
  • Data models and relationships
  • Database queries
  • Dependencies and imports

Then it generates Python code with:

  • FastAPI endpoints with proper type hints
  • Pydantic models for data validation
  • OpenAPI specifications
  • Property-based tests using Hypothesis

Strangler Pattern Implementation

The demo showcases safe, incremental migration:

Docker Compose Orchestration:

services:
  gateway:
    image: nginx:alpine
    ports: ["8888:80"]
    depends_on: [legacy-php, new-api]

  legacy-php:
    build: ./legacy-php
    ports: ["8080:80"]

  new-api:
    build: ./new-api
    ports: ["8000:8000"]
Enter fullscreen mode Exit fullscreen mode

Nginx Gateway Routing:

# Route /api/* to new Python API
location /api/ {
    proxy_pass http://new-api:8000;
}

# Route everything else to legacy PHP
location / {
    proxy_pass http://legacy-php:80;
}
Enter fullscreen mode Exit fullscreen mode

This allows incremental migration - move one endpoint at a time from PHP to Python while both systems run simultaneously.

Property-Based Testing: The Secret Weapon

Traditional unit tests check specific examples. Property-based tests verify universal properties across ALL inputs.

Example: Gateway Routing Correctness

#!/bin/bash
# Property 1: Gateway routes requests to correct backend

for i in {1..100}; do
    # Generate random path
    if [ $((RANDOM % 2)) -eq 0 ]; then
        PATH="/api/requests"
        EXPECTED="new-api"
    else
        PATH="/requests"
        EXPECTED="legacy-php"
    fi

    # Test routing
    curl -s "http://localhost:8888$PATH"
    # Verify correct backend handled request
done
Enter fullscreen mode Exit fullscreen mode

Python Property Test with Hypothesis:

from hypothesis import given, strategies as st

@given(st.integers(min_value=1, max_value=7))
def test_api_returns_matching_id(request_id):
    """For ANY valid ID, returned object should have matching ID"""
    response = client.get(f"/requests/{request_id}")
    assert response.status_code == 200
    assert response.json()["id"] == request_id
Enter fullscreen mode Exit fullscreen mode

This runs 100+ iterations with random inputs, catching edge cases you'd never think to test manually.

Working with Kiro: The Development Process

Spec-Driven Development

For the Strangler Studio demo, I used Kiro's spec-driven approach:

1. Requirements (EARS format):

WHEN a request is made to /api/requests 
THEN the Gateway SHALL route it to the new Python API

WHEN a request is made to /requests 
THEN the Gateway SHALL route it to the legacy PHP application
Enter fullscreen mode Exit fullscreen mode

2. Design with Correctness Properties:

Property 1: Gateway routing correctness
For any request path, the gateway routes to the correct 
backend based on the path prefix.
Enter fullscreen mode Exit fullscreen mode

3. Task Breakdown:

- [ ] 1. Set up Docker Compose with three services
- [ ] 2. Implement Nginx gateway routing
- [ ] 3. Create legacy PHP application
- [ ] 4. Create new Python API
- [ ] 5. Write property-based tests
Enter fullscreen mode Exit fullscreen mode

Kiro executed tasks one by one, automatically referencing requirements and implementing correctness properties as tests.

Vibe Coding for Rapid Prototyping

For the migration tool UI, I used conversational iteration:

Me: "Create a Frankenstein laboratory theme with electric blue and toxic green. Add animations: floating logo, electric glow pulse, and lightning sparks."

Kiro: Generates 200+ lines of CSS with six simultaneous animations, GPU-accelerated properties, and hover effects

This flexibility was perfect for UI polish and rapid feature additions.

Steering Documents: Project-Specific Intelligence

I created four steering files in .kiro/steering/ that were automatically included in every conversation:

testing-standards.md:

- Use Hypothesis for property-based testing
- Minimum 100 iterations per test
- Tag format: # Feature: {name}, Property {n}: {description}
- Test patterns: invariants, round-trips, idempotence
Enter fullscreen mode Exit fullscreen mode

halloween-theme.md:

- Electric Blue: #00d4ff
- Toxic Green: #76ff03
- Font: Cinzel (headings), Inter (body)
- No cheap emojis or generic Halloween clichés
Enter fullscreen mode Exit fullscreen mode

This transformed Kiro from a general assistant into a domain expert for my project. Every response was consistent with project conventions without me repeating myself.

Technical Challenges and Solutions

Challenge 1: Docker Port Conflicts

Problem: Port 80 already allocated on host system.

Solution: Changed gateway to port 8888, updated all documentation. Created PORT_CHANGES_SUMMARY.md to track the change.

Challenge 2: Git Not Found in Docker

Problem: Backend container couldn't clone GitHub repositories.

Solution: Updated Dockerfile to install git:

RUN apt-get update && apt-get install -y git
ENV GIT_PYTHON_REFRESH=quiet
ENV GIT_PYTHON_GIT_EXECUTABLE=/usr/bin/git
Enter fullscreen mode Exit fullscreen mode

Challenge 3: Vercel Serverless Limitations

Problem: 10-second timeout on free tier fails for large repos.

Solution: Implemented shallow cloning (depth=1), optimized analysis, documented upgrade path to Pro tier ($20/month for 60-second timeout).

Challenge 4: Logo Not Showing After Deployment

Problem: Added logo after Docker build, so it wasn't in the container.

Solution: Created rebuild scripts and documentation explaining Docker's immutable nature. Containers capture files at build time - changes require rebuilds.

The Results

What I Accomplished:

  • Complete end-to-end migration tool
  • Working Strangler pattern demo
  • Property-based test suite
  • 15+ documentation files
  • Production-ready code quality
  • Deployed to Vercel in 15 minutes

Code Quality Metrics:

  • Type safety throughout (Pydantic models, TypeScript)
  • Comprehensive error handling
  • Security headers and CORS configuration
  • 100+ property-based test iterations
  • OpenAPI contract validation

Development Speed:
What would normally take weeks took days, thanks to Kiro's assistance.

Key Learnings

1. Property-Based Testing is Powerful

Hypothesis finds edge cases you'd never think to test. It requires different thinking (properties vs examples) but catches more bugs.

2. Spec-Driven Development Ensures Quality

Clear requirements prevent misunderstandings. Correctness properties ensure quality. Task-by-task execution is systematic.

3. Steering Documents are Game-Changers

They transform Kiro from a general assistant into a domain expert. Every response follows project conventions automatically.

4. The Strangler Pattern Works

Incremental migration is safer than big-bang rewrites. The gateway pattern allows gradual transition with zero downtime.

5. Documentation is a Feature

Good docs are as important as good code. Users need multiple entry points: quick start, detailed guide, troubleshooting, reference.

Real-World Impact

This solves a real problem for Japanese companies (and companies worldwide) trapped by legacy PHP. The tool provides:

  • Automated analysis - No more manual code review
  • Intelligent generation - Production-ready Python code
  • Safe migration - Strangler pattern with zero downtime
  • Comprehensive testing - Property-based tests ensure correctness

Companies can now modernize without fear. No more months-long rewrite projects. No more choosing between maintenance and innovation.

What's Next

Immediate improvements:

  • Support for Laravel, Symfony, WordPress frameworks
  • Database schema extraction and migration
  • AI-powered code optimization
  • Multi-language support (Ruby, Java, Node.js to Python)

Long-term vision:

  • Japanese language UI and documentation
  • Integration with Japanese cloud providers
  • Enterprise features (SSO, audit logging)
  • Open-source core with plugin ecosystem

The ultimate goal: Make legacy PHP migration so easy that Japanese companies can modernize without fear.

Try It Yourself

GitHub Repository: https://github.com/mongonsh/Strangler-Studio-with-PHP-Migration-Tool

Deploy to Vercel: Follow the guides in the repo - you can have it running in 15 minutes.

Tech Stack:

  • Frontend: React, Vite, TailwindCSS
  • Backend: FastAPI, Pydantic, GitPython, Hypothesis
  • Demo: PHP 8, FastAPI, Nginx, Docker
  • Testing: Pytest, Hypothesis, Bash scripts
  • Deployment: Vercel (serverless)

Conclusion

This hackathon taught me that the future of software development isn't human OR AI - it's human AND AI working together.

I provided the vision: solve the legacy PHP problem plaguing Japanese companies.

Kiro provided the execution: production-ready code, comprehensive tests, beautiful UI, thorough documentation.

Together, we built something that would have taken weeks in just days.

Legacy PHP doesn't have to be a death sentence. With the right tools, even the oldest code can be reborn.

"It's alive!"


*Built with Kiro IDE during Kiroween *


#kiro #hackathon #php #python #fastapi #migration #legacy #strangler-pattern #property-based-testing #ai-assisted-development


What do you think? Would you use a tool like this for your legacy projects? Drop a comment below!

Top comments (0)