code-migration
JavaScriptからTypeScriptへの変換、Reactのhooks移行、Vue 2からVue 3へのアップデートなど、フレームワークや言語、APIバージョンの異なるコードを、互換性を保ちつつ段階的に移行・現代化するSkill。
📜 元の英語説明(参考)
Migrate codebases between frameworks, languages, and API versions. Use when a user asks to convert JavaScript to TypeScript, migrate React class components to hooks, upgrade Vue 2 to Vue 3, migrate Python 2 to 3, update deprecated APIs, switch ORMs, convert Express to Fastify, or modernize legacy code. Handles incremental migration with backward compatibility.
🇯🇵 日本人クリエイター向け解説
JavaScriptからTypeScriptへの変換、Reactのhooks移行、Vue 2からVue 3へのアップデートなど、フレームワークや言語、APIバージョンの異なるコードを、互換性を保ちつつ段階的に移行・現代化するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o code-migration.zip https://jpskill.com/download/14764.zip && unzip -o code-migration.zip && rm code-migration.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14764.zip -OutFile "$d\code-migration.zip"; Expand-Archive "$d\code-migration.zip" -DestinationPath $d -Force; ri "$d\code-migration.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
code-migration.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
code-migrationフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
コード移行
概要
自動化された段階的な変換により、フレームワーク、言語、APIバージョン間でコードベースを移行します。このスキルは、JavaScriptからTypeScriptへの変換、フレームワークのアップグレード、非推奨APIの置換、ORMの移行を、機能を維持し、下位互換性を保ちながら処理します。
手順
ユーザーがコードの移行または最新化を依頼した場合、次の手順に従ってください。
ステップ 1: 移行範囲の評価
コードベースを分析して、以下を理解します。
- ソース: 現在のフレームワーク/言語バージョン
- ターゲット: 希望するフレームワーク/言語バージョン
- サイズ: 影響を受けるファイル数と行数
- 依存関係: 更新または置換が必要なライブラリ
- リスク領域: カスタムパッチ、モンキーパッチ、またはフレームワーク内部の使用
# 影響を受けるファイルの数を数える
find src -name "*.js" | wc -l # JS→TS 移行
grep -rl "React.Component" src/ # Class→hooks 移行
grep -rl "Vue.component" src/ # Vue 2 パターン
ステップ 2: 移行計画の作成
コードを変更する前に、移行計画を作成します。
## 移行計画: JS → TypeScript
**移行するファイル:** 47
**推定工数:** AI支援で約2時間
### フェーズ 1: セットアップ (非破壊)
- allowJs: true で tsconfig.json を追加
- TypeScript と型パッケージをインストール
- エントリーポイントの名前を .ts に変更
### フェーズ 2: 段階的な変換 (ファイルごと)
- .js → .ts/.tsx に名前を変更
- 関数シグネチャに型アノテーションを追加
- `any` を適切な型に置き換える
- 型エラーを修正
### フェーズ 3: 厳密モード
- tsconfig で strict: true を有効にする
- 残りの `any` 型を解決する
- 戻り値の型アノテーションを追加
ステップ 3: ファイルごとに移行を実行
ファイルを段階的に処理し、各変更を検証します。
JavaScript → TypeScript:
// BEFORE: src/utils/api.js
const fetchUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('User not found');
return response.json();
};
module.exports = { fetchUser };
// AFTER: src/utils/api.ts
interface User {
id: string;
email: string;
name: string;
createdAt: string;
}
export const fetchUser = async (id: string): Promise<User> => {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('User not found');
return response.json() as Promise<User>;
};
React class → hooks:
// BEFORE
class UserProfile extends React.Component {
state = { user: null, loading: true };
componentDidMount() {
fetchUser(this.props.id).then(user =>
this.setState({ user, loading: false })
);
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
this.setState({ loading: true });
fetchUser(this.props.id).then(user =>
this.setState({ user, loading: false })
);
}
}
render() {
if (this.state.loading) return <Spinner />;
return <div>{this.state.user.name}</div>;
}
}
// AFTER
function UserProfile({ id }: { id: string }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
fetchUser(id).then(user => {
setUser(user);
setLoading(false);
});
}, [id]);
if (loading) return <Spinner />;
return <div>{user?.name}</div>;
}
Vue 2 → Vue 3 (Options → Composition API):
<!-- BEFORE: Vue 2 Options API -->
<script>
export default {
data() {
return { count: 0, items: [] };
},
computed: {
total() { return this.items.reduce((s, i) => s + i.price, 0); }
},
mounted() { this.fetchItems(); },
methods: {
async fetchItems() {
this.items = await api.getItems();
}
}
};
</script>
<!-- AFTER: Vue 3 Composition API -->
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
const count = ref(0);
const items = ref<Item[]>([]);
const total = computed(() => items.value.reduce((s, i) => s + i.price, 0));
async function fetchItems() {
items.value = await api.getItems();
}
onMounted(fetchItems);
</script>
ステップ 4: 依存関係と構成の更新
# JS→TS の場合
npm install -D typescript @types/node @types/react
npx tsc --init
# Vue 2→3 の場合
npm install vue@3 @vue/compiler-sfc
npm uninstall vue-template-compiler
# インポートパス、ビルド構成 (vite/webpack)、およびエイリアスを更新
ステップ 5: 移行後の検証
各ファイルまたはバッチの後:
- 型チェッカーを実行:
npx tsc --noEmit - 既存のテストを実行:
npm test - リンターを実行:
npx eslint src/ - プロジェクトをビルド:
npm run build
エラーを報告し、続行する前に修正してください。
例
例 1: Express.js プロジェクトを JavaScript から TypeScript に移行する
ユーザーリクエスト: "Express アプリを JS から TS に変換してください"
実行されたアクション:
- プロジェクトを分析: 23 個の JS ファイル、Express 4.18、既存の型なし
- TypeScript、
@types/express、@types/node、ts-nodeをインストール - 段階的な移行のために
allowJs: trueでtsconfig.jsonを作成 - リーフモジュール (utils、models) から始めて、ファイル名を
.js→.tsに変更 - リクエスト/レスポンスボディのインターフェースを追加
require→import、module.exports→exportに変換- ルートハンドラーに型アノテーションを追加
結果:
移行されたファイル: 23/23
修正された型エラー: 41
作成された新しいインターフェース: 8 (User, Product, Order, ApiError, etc.)
ビルド: ✅ 合格
テスト: ✅ 34/34 合格
例 2: 非推奨の React Router v5 を v6 に更新する
ユーザーリクエスト: "アプリを React Router 5 から 6 にアップグレードしてください"
実行されたアクション:
- React Router v5 API を使用している 12 個のファイルを特定
- 変換を適用:
<Switch>→<Routes><Route component={X}>→<Route element={<X />}>useHistory()→useNavigate()<Redirect to="/">→<Navigate to="/" replace>- ネストされたルートを
<Outlet />で再構築
react-router-domを v6.20 に更新
移行前/移行後:
// v5
<Switch>
<Route exact path="/" component={Home} />
<Route path="/use 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Code Migration
Overview
Migrate codebases between frameworks, languages, and API versions with automated, incremental transformations. This skill handles JavaScript-to-TypeScript conversions, framework upgrades, deprecated API replacements, and ORM migrations while preserving functionality and maintaining backward compatibility.
Instructions
When a user asks to migrate or modernize their code, follow these steps:
Step 1: Assess the migration scope
Analyze the codebase to understand:
- Source: Current framework/language version
- Target: Desired framework/language version
- Size: Number of files and lines affected
- Dependencies: Libraries that need updating or replacing
- Risk areas: Custom patches, monkey-patches, or framework internals usage
# Count affected files
find src -name "*.js" | wc -l # JS→TS migration
grep -rl "React.Component" src/ # Class→hooks migration
grep -rl "Vue.component" src/ # Vue 2 patterns
Step 2: Create a migration plan
Before changing code, produce a migration plan:
## Migration Plan: JS → TypeScript
**Files to migrate:** 47
**Estimated effort:** ~2 hours with AI assistance
### Phase 1: Setup (non-breaking)
- Add tsconfig.json with allowJs: true
- Install TypeScript and type packages
- Rename entry point to .ts
### Phase 2: Incremental conversion (file by file)
- Rename .js → .ts/.tsx
- Add type annotations to function signatures
- Replace `any` with proper types
- Fix type errors
### Phase 3: Strict mode
- Enable strict: true in tsconfig
- Resolve remaining `any` types
- Add return type annotations
Step 3: Execute the migration file by file
Process files incrementally, verifying each change:
JavaScript → TypeScript:
// BEFORE: src/utils/api.js
const fetchUser = async (id) => {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('User not found');
return response.json();
};
module.exports = { fetchUser };
// AFTER: src/utils/api.ts
interface User {
id: string;
email: string;
name: string;
createdAt: string;
}
export const fetchUser = async (id: string): Promise<User> => {
const response = await fetch(`/api/users/${id}`);
if (!response.ok) throw new Error('User not found');
return response.json() as Promise<User>;
};
React class → hooks:
// BEFORE
class UserProfile extends React.Component {
state = { user: null, loading: true };
componentDidMount() {
fetchUser(this.props.id).then(user =>
this.setState({ user, loading: false })
);
}
componentDidUpdate(prevProps) {
if (prevProps.id !== this.props.id) {
this.setState({ loading: true });
fetchUser(this.props.id).then(user =>
this.setState({ user, loading: false })
);
}
}
render() {
if (this.state.loading) return <Spinner />;
return <div>{this.state.user.name}</div>;
}
}
// AFTER
function UserProfile({ id }: { id: string }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
setLoading(true);
fetchUser(id).then(user => {
setUser(user);
setLoading(false);
});
}, [id]);
if (loading) return <Spinner />;
return <div>{user?.name}</div>;
}
Vue 2 → Vue 3 (Options → Composition API):
<!-- BEFORE: Vue 2 Options API -->
<script>
export default {
data() {
return { count: 0, items: [] };
},
computed: {
total() { return this.items.reduce((s, i) => s + i.price, 0); }
},
mounted() { this.fetchItems(); },
methods: {
async fetchItems() {
this.items = await api.getItems();
}
}
};
</script>
<!-- AFTER: Vue 3 Composition API -->
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
const count = ref(0);
const items = ref<Item[]>([]);
const total = computed(() => items.value.reduce((s, i) => s + i.price, 0));
async function fetchItems() {
items.value = await api.getItems();
}
onMounted(fetchItems);
</script>
Step 4: Update dependencies and configuration
# For JS→TS
npm install -D typescript @types/node @types/react
npx tsc --init
# For Vue 2→3
npm install vue@3 @vue/compiler-sfc
npm uninstall vue-template-compiler
# Update import paths, build config (vite/webpack), and aliases
Step 5: Verify after migration
After each file or batch:
- Run the type checker:
npx tsc --noEmit - Run existing tests:
npm test - Run the linter:
npx eslint src/ - Build the project:
npm run build
Report any errors and fix them before proceeding.
Examples
Example 1: Migrate an Express.js project from JavaScript to TypeScript
User request: "Convert my Express app from JS to TS"
Actions taken:
- Analyzed project: 23 JS files, Express 4.18, no existing types
- Installed TypeScript,
@types/express,@types/node,ts-node - Created
tsconfig.jsonwithallowJs: truefor incremental migration - Renamed files
.js→.tsstarting from leaf modules (utils, models) - Added interfaces for request/response bodies
- Converted
require→import,module.exports→export - Added type annotations to route handlers
Result:
Files migrated: 23/23
Type errors fixed: 41
New interfaces created: 8 (User, Product, Order, ApiError, etc.)
Build: ✅ passing
Tests: ✅ 34/34 passing
Example 2: Update deprecated React Router v5 to v6
User request: "Upgrade our app from React Router 5 to 6"
Actions taken:
- Identified 12 files using React Router v5 APIs
- Applied transformations:
<Switch>→<Routes><Route component={X}>→<Route element={<X />}>useHistory()→useNavigate()<Redirect to="/">→<Navigate to="/" replace>- Nested routes restructured with
<Outlet />
- Updated
react-router-domto v6.20
Before/After:
// v5
<Switch>
<Route exact path="/" component={Home} />
<Route path="/users/:id" component={UserProfile} />
<Redirect to="/" />
</Switch>
// v6
<Routes>
<Route path="/" element={<Home />} />
<Route path="/users/:id" element={<UserProfile />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
Result: 12 files updated, 0 type errors, all 28 tests passing.
Guidelines
- Always migrate incrementally — one file or module at a time. Never attempt a big-bang rewrite.
- Create the migration plan before writing any code. Share it with the user for approval on large projects.
- For JS→TS, start with
strict: falseandallowJs: true, then tighten after all files are converted. - Preserve existing behavior exactly. Migration should not change functionality.
- Run tests after every file migration. If tests break, fix before proceeding.
- When migrating frameworks, check the official migration guide first (e.g., Vue 2→3, Angular upgrade guide).
- Handle deprecated APIs by checking the library's changelog for the recommended replacement.
- For large codebases (100+ files), suggest migrating in phases across multiple PRs.
- Keep
require/importstyle consistent within each file during migration — don't mix. - Add type annotations starting with function signatures, then variables, then generics. Don't over-type.