10 Prompts for Code Migration: Python 2→3, JavaScript→TypeScript, REST→GraphQL
Code migration is one of the most delicate tasks in software engineering. Moving from Python 2 to Python 3, from plain JavaScript to TypeScript, or from REST APIs to GraphQL can break production systems if done manually without careful planning. However, with the right prompts, you can automate large portions of the migration process using AI assistants like GPT-4o, Claude 3.5 Sonnet, or specialized tools.
In this article, I share 10 practical prompts organized by category — basic, advanced, and expert — that will help you migrate code safely and efficiently. Each prompt includes a clear task, the exact prompt text, and a realistic example result.
Why Prompt-Driven Migration Matters
Manual code migration is error-prone and time-consuming. According to a 2023 survey by Stripe (source: Stripe Developer Survey 2023), developers spend an average of 17 hours per week on maintenance tasks, including refactoring and migration. AI-assisted prompts can reduce that time by up to 40% while catching subtle issues like deprecated APIs or type mismatches.
Let’s dive into the prompts, starting with basic ones for beginners.
Basic Prompts (Beginner Level)
1. Python 2 to Python 3 — Print Statement Migration
Task: Convert a Python 2 script that uses print as a statement to Python 3 syntax using print() as a function.
Prompt:
Convert the following Python 2 code to Python 3. Replace all print statements with print() function calls. Also update any xrange() to range() and fix integer division if needed:
```python
# Python 2 code
for i in xrange(10):
print "Iteration", i
if i % 2 == 0:
print i / 2
**Example Result:**
```python
# Python 3 code
for i in range(10):
print("Iteration", i)
if i % 2 == 0:
print(i // 2) # integer division preserved
2. JavaScript to TypeScript — Basic Type Annotations
Task: Add type annotations to a simple JavaScript function that calculates the area of a rectangle.
Prompt:
Convert the following JavaScript function to TypeScript. Add type annotations for parameters and return value:
```javascript
function calculateArea(width, height) {
return width * height;
}
**Example Result:**
```typescript
function calculateArea(width: number, height: number): number {
return width * height;
}
3. REST to GraphQL — Simple Query Translation
Task: Translate a REST endpoint (GET /users/1) to a GraphQL query.
Prompt:
Translate this REST API call to a GraphQL query. The REST endpoint returns a user object with id, name, and email fields. Show both the query and the expected response.
Example Result:
query {
user(id: 1) {
id
name
email
}
}
Expected response:
{
"data": {
"user": {
"id": 1,
"name": "Alice",
"email": "alice@example.com"
}
}
}
Advanced Prompts (Intermediate Level)
4. Python 2 to Python 3 — Handling Unicode and Bytes
Task: Migrate a script that reads a file and processes strings, handling the Python 2 Unicode vs bytes distinction.
Prompt:
Migrate this Python 2 code to Python 3. Pay special attention to unicode/bytes handling. Use open() with encoding parameter where appropriate:
```python
# Python 2
with open('data.txt', 'r') as f:
content = f.read()
for line in content.split('\n'):
if isinstance(line, unicode):
print line.encode('utf-8')
else:
print line
**Example Result:**
```python
# Python 3
with open('data.txt', 'r', encoding='utf-8') as f:
content = f.read()
for line in content.split('\n'):
print(line) # no unicode/bytes distinction needed
5. JavaScript to TypeScript — Class and Interface Migration
Task: Convert a JavaScript ES6 class with a constructor and methods to TypeScript with typed properties and an interface.
Prompt:
Convert this JavaScript class to TypeScript. Create an interface for the constructor parameters and add type annotations to all methods and properties:
```javascript
class Product {
constructor(name, price) {
this.name = name;
this.price = price;
}
applyDiscount(discount) {
return this.price * (1 - discount);
}
}
**Example Result:**
```typescript
interface ProductParams {
name: string;
price: number;
}
class Product {
name: string;
price: number;
constructor(params: ProductParams) {
this.name = params.name;
this.price = params.price;
}
applyDiscount(discount: number): number {
return this.price * (1 - discount);
}
}
6. REST to GraphQL — Mutation with Error Handling
Task: Translate a REST POST endpoint (POST /users) to a GraphQL mutation, including error handling.
Prompt:
Translate this REST mutation to GraphQL. The REST endpoint creates a user and returns either the user object or an error. Show the GraphQL mutation with input type and error handling using a union type.
Example Result:
mutation CreateUser($input: CreateUserInput!) {
createUser(input: $input) {
... on User {
id
name
email
}
... on ValidationError {
message
field
}
... on ServerError {
message
}
}
}
Variables:
{
"input": {
"name": "Bob",
"email": "bob@example.com"
}
}
Expert Prompts (Advanced Level)
7. Python 2 to Python 3 — Full Project Migration with 2to3 Automation
Task: Create a script that automates migration of an entire Python project, including custom fixes for deprecated libraries like urllib2.
Prompt:
Write a Python script that uses the `2to3` library to automate migration of a Python 2 project to Python 3. Include custom fixes for the following:
- Replace urllib2 with urllib.request and urllib.error
- Convert ConfigParser to configparser
- Fix relative imports for Python 3
- Add __future__ imports (print_function, division, absolute_import)
The script should accept a directory path and output a diff of changes.
Example Result (partial):
import subprocess
import sys
from pathlib import Path
def migrate_project(project_dir: str):
dir_path = Path(project_dir)
if not dir_path.exists():
print(f"Directory {project_dir} not found", file=sys.stderr)
return
# Run 2to3 with custom fixes
result = subprocess.run(
["2to3", "--output-dir", str(dir_path / "migrated"), "--write", "--nobackups",
"--add-suffix", "_py3", str(dir_path)],
capture_output=True, text=True
)
print(result.stdout)
if result.stderr:
print("Errors:", result.stderr, file=sys.stderr)
8. JavaScript to TypeScript — Full React Component Migration
Task: Convert a React component from JavaScript to TypeScript, including props interface and state typing.
Prompt:
Convert this React component from JavaScript to TypeScript. Define interfaces for props and state. Use React.FC type for the component:
```jsx
import React, { useState } from 'react';
function Counter({ initialCount, step }) {
const [count, setCount] = useState(initialCount || 0);
const increment = () => setCount(count + step);
const decrement = () => setCount(count - step);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
}
**Example Result:**
```tsx
import React, { useState } from 'react';
interface CounterProps {
initialCount?: number;
step: number;
}
const Counter: React.FC<CounterProps> = ({ initialCount = 0, step }) => {
const [count, setCount] = useState<number>(initialCount);
const increment = (): void => setCount(count + step);
const decrement = (): void => setCount(count - step);
return (
<div>
<p>Count: {count}</p>
<button onClick={increment}>+</button>
<button onClick={decrement}>-</button>
</div>
);
};
export default Counter;
9. REST to GraphQL — Full API Migration with Batching
Task: Design a migration strategy from REST to GraphQL for a blog API, including batching requests to avoid N+1 problem.
Prompt:
Design a GraphQL schema and resolver for a blog API that currently has these REST endpoints:
- GET /posts (list all posts)
- GET /posts/:id (single post)
- GET /posts/:id/comments (comments for a post)
- GET /users/:id (author info)
Include a batching solution using DataLoader to avoid N+1 queries when fetching authors for multiple posts.
Example Result (partial schema):
type Query {
posts: [Post!]!
post(id: ID!): Post
}
type Post {
id: ID!
title: String!
body: String!
author: User!
comments: [Comment!]!
}
type User {
id: ID!
name: String!
email: String!
}
type Comment {
id: ID!
text: String!
author: User!
}
Resolver example (JavaScript with DataLoader):
const DataLoader = require('dataloader');
const batchUsers = async (ids) => {
const users = await db.users.findAll({ where: { id: ids } });
return ids.map(id => users.find(user => user.id === id));
};
const userLoader = new DataLoader(batchUsers);
const resolvers = {
Post: {
author: (parent) => userLoader.load(parent.authorId),
},
};
10. Multi-Step Migration — Python 2 to 3, then to TypeScript (via Pyodide)
Task: Create a pipeline that migrates Python 2 code to Python 3, then uses Pyodide to run the Python 3 code in a browser environment, and finally wraps it in TypeScript types.
Prompt:
Design a migration pipeline for a Python 2 library that performs data processing. The steps:
1. Convert Python 2 to Python 3 using 2to3
2. Wrap the Python 3 code for Pyodide (WebAssembly Python) execution
3. Create TypeScript type definitions for the Python functions exposed to JavaScript
Provide example code for each step.
Example Result:
Step 1: Run 2to3 on the Python file.
Step 2: Wrap for Pyodide:
# data_processor.py (Python 3)
def process_data(data: list) -> list:
return [x * 2 for x in data]
Step 3: TypeScript types:
// types.ts
export interface DataProcessor {
processData(data: number[]): number[];
}
// Usage with Pyodide
import { loadPyodide } from 'pyodide';
const pyodide = await loadPyodide();
await pyodide.loadPackage('micropip');
await pyodide.runPythonAsync(`
from data_processor import process_data
`);
const result: number[] = pyodide.globals.get('process_data')([1, 2, 3]);
console.log(result); // [2, 4, 6]
Best Practices for Prompt-Driven Migration
- Always test generated code — AI can produce syntactically correct but semantically wrong code. Use unit tests before deploying.
- Use version control — Apply migrations in a branch and review diffs carefully.
- Incremental migration — Migrate module by module rather than the whole codebase at once.
- Document deprecated APIs — Keep a list of removed or changed APIs for future reference.
Conclusion
Code migration doesn’t have to be a nightmare. With well-crafted prompts, you can automate repetitive tasks, catch edge cases, and reduce the risk of introducing bugs. Whether you’re moving from Python 2 to 3, adding TypeScript types, or adopting GraphQL, these 10 prompts will save you hours of manual work.
Remember: AI is a tool, not a replacement for human review. Always validate the output and test thoroughly. Happy migrating!
Comments