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
];
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;
}
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']
}
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"]
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;
}
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
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
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
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.
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
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
halloween-theme.md:
- Electric Blue: #00d4ff
- Toxic Green: #76ff03
- Font: Cinzel (headings), Inter (body)
- No cheap emojis or generic Halloween clichés
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
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)