Language Migration

Migrate PHP to Python, JavaScript to TypeScript, or any language to any other. AI handles the translation - you guide the strategy.

Intermediate 13 min read Lesson 15 of 20

Migration Strategy

Never migrate an entire codebase in one shot. Use this strategy:

Migration workflow
Phase 1 - Inventory (1 session):
> Read the entire codebase. Create a migration plan:
  1. List all files grouped by: models, services, controllers, utilities, views
  2. Identify external library dependencies and their target-language equivalents
  3. Flag any language-specific features that need idiomatic rewriting
  4. Recommend migration order (start with lowest dependencies)

Phase 2 - Utilities first (1 session per file):
> Migrate StringHelper.php to Python (string_helper.py).
  Use idiomatic Python - no direct translation.
  Use Python string methods instead of PHP's str_* functions.

Phase 3 - Models (1 session per model):
> Migrate UserModel.php to Python using SQLAlchemy ORM.
  Map PDO prepared statements to SQLAlchemy queries.
  Keep the same method names and return types.

Phase 4 - Services + Controllers (1 session per file):
> Migrate AuthService.php to Python using Flask routes.
  Convert PHP sessions to Flask's session object.

Phase 5 - Verify parity:
> Write Python tests that verify the migrated code produces
  the same outputs as the PHP code for the same inputs.

PHP to Python

PHP utility to Python
> Migrate this PHP utility class to Python:
  [paste PHP class]

  Target: Python 3.11
  Style: use type hints, docstrings, pythonic idioms (no direct PHP translation)
  Replace PHP functions with Python equivalents:
  - array_map -> list comprehension or map()
  - array_filter -> list comprehension or filter()
  - implode/explode -> str.join() / str.split()
  - isset() -> if key in dict / is not None
  - empty() -> not value

  Output: Python file with same filename (snake_case), same methods.
PHP PDO model to Python SQLAlchemy
> Migrate UserModel.php to Python using SQLAlchemy.

  PHP source:
  [paste UserModel.php]

  Target:
  - Python 3.11 + SQLAlchemy 2.0
  - Use declarative model class (class User(Base))
  - findById -> session.get(User, id)
  - findByEmail -> session.scalar(select(User).where(User.email == email))
  - create -> session.add(User(...)); session.commit()
  - Passwords: use bcrypt (passlib library) instead of PHP's password_hash

  Show: models/user.py with SQLAlchemy model + methods.
PHP web app to Flask API
> Migrate this PHP REST API endpoint to Python Flask:

  PHP: [paste api/users.php - GET /api/users, POST /api/users, etc.]

  Target:
  - Python 3.11 + Flask 3.0
  - Use Flask Blueprints (create users_bp blueprint)
  - Use Flask-SQLAlchemy for DB operations
  - Return jsonify() instead of json_encode()
  - Auth: Flask session or JWT (keep same auth mechanism as original)
  - HTTP status codes: same as original

  Output: routes/users.py using Blueprint

JavaScript to TypeScript

JS to TS is the most common and easiest migration - the languages are nearly identical, you just add types.

JS to TypeScript prompts
# Convert a single file:
> Convert this JavaScript file to TypeScript:
  [paste app.js]

  Add type annotations to:
  - All function parameters and return types
  - Variables where the type is not obvious from assignment
  - Create interfaces for object shapes that are used in multiple places
  - Use strict mode (add tsconfig with strict: true)
  - Keep all logic identical - only add types

# Convert a project:
> I have a Node.js Express project in JavaScript.
  Help me migrate it to TypeScript:

  Step 1: Create tsconfig.json for Node.js with strict mode
  Step 2: Rename all .js files to .ts and add types to user.js (the data model)
  Step 3: Create interfaces for: User, Product, Order (based on the database schema I show you)
  Step 4: Update routes/users.js to routes/users.ts with typed Request/Response

  Read the project first, then do Step 1.

# Add types to Express routes:
> Read routes/users.js. Convert to TypeScript.
  Add proper typing:
  - Use Request for route handlers
  - Create a UserRequest interface extending Request
  - Type all middleware functions
  - No use of 'any' type

Python to Go

Python to Go migration prompts
> Migrate this Python function to Go:
  [paste Python function]

  Target: Go 1.22
  Use idiomatic Go:
  - Return (value, error) instead of raising exceptions
  - Use structs instead of dicts for data models
  - Use goroutines for anything currently using threading/asyncio
  - No direct Python translation - write idiomatic Go

# Migrate a Python data model:
> Migrate User class from Python/SQLAlchemy to Go using database/sql:
  [paste Python User model]

  Create:
  - models/user.go: User struct with proper json/db tags
  - db/user_repository.go: UserRepository with FindByID, FindByEmail, Create, Update

# Migrate Flask API to Go Gin:
> Migrate this Flask route to Go using the Gin framework:
  [paste Flask route]

  - Use gin.Context instead of request/response
  - Return c.JSON() instead of jsonify()
  - Auth middleware using gin.HandlerFunc
  - Same URL pattern and HTTP method

Universal Migration Template

This template works for any language-to-language migration:

Universal migration prompt
> Migrate this [SOURCE LANGUAGE] code to [TARGET LANGUAGE]:

[paste source code]

Migration requirements:
1. Target: [TARGET LANGUAGE version]
2. Framework/libraries: [what to use in target]
3. Style: Write idiomatic [TARGET LANGUAGE] - do NOT directly translate syntax
4. Library mapping:
   [SOURCE lib] -> [TARGET equivalent]
   [SOURCE lib] -> [TARGET equivalent]
5. Preserve: exact same function/method names and return values
6. Error handling: use [TARGET LANGUAGE]'s idiomatic error handling
7. Show a side-by-side comparison of the most important patterns that changed

Output: the migrated file + a note of any manual steps needed

Verifying the Migration

Post-migration verification prompts
> Write tests in [TARGET LANGUAGE] that verify the migrated code
  produces identical outputs to the original [SOURCE LANGUAGE] code
  for the same inputs.

  Test cases to cover:
  - Normal input: [example]
  - Edge case: empty/null input
  - Error case: invalid input that should return error

> Compare the behavior of the PHP version and Python version
  for this input: [test case].
  Which file handles it differently?

> Run the migrated code and show me any runtime errors.
  Fix them.

Frequently Asked Questions

Not in one prompt. Migrate file by file or class by class. Start with the data models (no dependencies), then utility functions, then the service layer, then controllers/routes. Each file is a standalone migration task with its own session.

For standard patterns (functions, classes, loops, conditionals): very accurate. For language-specific features (PHP generators, Python decorators, Go goroutines): good but needs testing. Business logic: accurate. Platform-specific things (PHP sessions, Python asyncio): needs idiomatic rewriting that AI handles well when asked explicitly.

This is the hardest part. PHP's PDO does not have a 1:1 Python equivalent - you use SQLAlchemy or psycopg2 instead. Always ask the AI: "What is the Python/Go/etc. equivalent of [library]?" before migrating code that uses it. The migration prompt should specify the target library.