Create React Appの廃止について
2025年2月14日 by Matt Carroll and Ricky Hanlon
本日、新しいアプリでのCreate React Appを非推奨とし、既存のアプリにはフレームワークへの移行、またはVite、Parcel、RSBuildなどのビルドツールへの移行を推奨します。また、フレームワークがプロジェクトに適さない場合、独自のフレームワークを構築したい場合、またはReactアプリをゼロから構築してReactの動作を学びたい場合のためのドキュメントも提供しています。
2016年にCreate React Appをリリースした当時、新しいReactアプリを構築する明確な方法はありませんでした。Reactアプリを作成するには、JSX、リンティング、ホットリロードなどの基本機能をサポートするために、多くのツールをインストールして自分で組み合わせる必要がありました。これを正しく行うのは非常に困難だったため、コミュニティは一般的なセットアップ用のボイラープレートを作成しました。
しかし、ボイラープレートは更新が困難で、断片化によりReactが新機能をリリースすることが困難になりました。Create React Appは、複数のツールを単一の推奨構成に組み合わせることで、これらの問題を解決しました。これにより、アプリは新しいツール機能に簡単にアップグレードでき、Reactチームは重要なツールの変更(Fast Refreshサポート、React Hooksのlintルール)を可能な限り広いオーディエンスに展開できるようになりました。
このモデルは非常に人気となり、現在このように動作するツールのカテゴリ全体が存在します。
Create React Appの非推奨化
Create React Appは開始を容易にしますが、高性能な本番アプリの構築を困難にするいくつかの制限があります。原則として、これらの問題を本質的にフレームワークに進化させることで解決できます。しかし、Create React Appには現在アクティブなメンテナーがおらず、これらの問題をすでに解決している多くの既存のフレームワークがあるため、Create React Appを非推奨にすることを決定しました。
本日より、新しいアプリをインストールすると、非推奨警告が表示されます:
create-react-app is deprecated. You can find a list of up-to-date React frameworks on react.dev
For more info see: react.dev/link/cra
このエラーメッセージはインストールごとに一度だけ表示されます。また、Create React AppのWebサイトとGitHubリポジトリにも非推奨通知を追加しました。
Create React Appはメンテナンスモードで動作し続け、React 19で動作するCreate React Appの新バージョンを公開しました。
フレームワークへの移行方法
新しいReactアプリはフレームワークで作成することを推奨します。推奨するすべてのフレームワークは、クライアントサイドレンダリング(CSR)とシングルページアプリ(SPA)をサポートし、サーバーなしでCDNや静的ホスティングサービスにデプロイできます。
既存のアプリについては、これらのガイドがクライアント専用SPAへの移行に役立ちます:
ビルドツールへの移行方法
アプリに特殊な制約がある場合、独自のフレームワークを構築してこれらの問題を解決したい場合、またはReactの動作をゼロから学びたい場合は、Vite、Parcel、Rsbuildを使用してReactで独自のカスタムセットアップを構築できます。
既存のアプリについては、これらのガイドがビルドツールへの移行に役立ちます:
Vite、Parcel、Rsbuildの使用開始を支援するため、Reactアプリをゼロから構築する新しいドキュメントを追加しました。
詳細解説
フレームワークは必要ですか?
ほとんどのアプリはフレームワークの恩恵を受けますが、Reactアプリをゼロから構築する有効なケースもあります。良い経験則として、アプリにルーティングが必要な場合、フレームワークの恩恵を受ける可能性があります。
SvelteにSveltekit、VueにNuxt、SolidにSolidStartがあるように、Reactはデータフェッチやコード分割などの機能にルーティングを完全に統合したフレームワークの使用を推奨します。これにより、複雑な設定を自分で書いて本質的にフレームワークを構築する必要がある苦痛を回避できます。
ただし、Vite、Parcel、Rsbuildなどのビルドツールを使用してReactアプリをゼロから構築することも常に可能です。ビルドツールの制限とフレームワークを推奨する理由について詳しく学ぶには、続きをお読みください。
ビルドツールの制限
Create React Appやそれに類似するビルドツールは、Reactアプリの構築を簡単に開始できます。npx create-react-app my-appを実行すると、開発サーバー、リンティング、本番ビルドを備えた完全に設定されたReactアプリが得られます。
例えば、内部管理ツールを構築している場合、ランディングページから始めることができます:
export default function App() {
return (
<div>
<h1>Welcome to the Admin Tool!</h1>
</div>
)
}
これにより、JSX、デフォルトのlintルール、開発と本番の両方で実行するバンドラーなどの機能を使用してReactですぐにコーディングを開始できます。
しかし、このセットアップには実際の本番アプリを構築するために必要なツールが不足しています。ほとんどの本番アプリには、ルーティング、データフェッチ、コード分割などの問題に対するソリューションが必要です。
ルーティング
Create React Appには特定のルーティングソリューションが含まれていません。始めたばかりの場合、一つの選択肢はuseStateを使用してルート間を切り替えることです。しかし、これを行うということは、アプリへのリンクを共有できないことを意味します - すべてのリンクが同じページに移動し、時間の経過とともにアプリの構造化が困難になります:
import { useState } from 'react';
import Home from './Home';
import Dashboard from './Dashboard';
export default function App() {
const [route, setRoute] = useState('home');
return (
<div>
{route === 'home' && <Home />}
{route === 'dashboard' && <Dashboard />}
</div>
)
}
これが、Create React Appを使用するほとんどのアプリがReact RouterやTanstack Routerなどのルーティングライブラリでルーティングを追加する理由です。
ルーティングライブラリを使用すると、アプリに追加のルートを追加でき、アプリの構造に関する意見を提供し、ルートへのリンクの共有を開始できます。例えば、React Routerでルートを定義できます:
import { RouterProvider, createBrowserRouter } from 'react-router';
import Home from './Home';
import Dashboard from './Dashboard';
const router = createBrowserRouter([
{ path: '/', element: <Home /> },
{ path: '/dashboard', element: <Dashboard /> }
]);
export default function App() {
return (
<RouterProvider value={router} />
)
}
この変更により、/dashboardへのリンクを共有でき、アプリはダッシュボードページに移動します。
ルーティングライブラリを使用すると、ネストされたルート、ルートガード、ルート遷移などの追加機能を追加できます。これらはルーティングライブラリなしでは実装が困難です。
ここでトレードオフが行われています:ルーティングライブラリはアプリに複雑さを追加しますが、それなしでは実装が困難な機能も追加します。
データフェッチ
Create React Appでのもう一つの一般的な問題はデータフェッチです。Create React Appには特定のデータフェッチソリューションが含まれていません。始めたばかりの場合、一般的な選択肢はエフェクト内でfetchを使用してデータを読み込むことです。しかし、これを行うということは、コンポーネントがレンダリングされた後にデータがフェッチされることを意味し、ネットワークウォーターフォールを引き起こす可能性があります。
ネットワークウォーターフォールは、コードのダウンロード中に並行してではなく、アプリがレンダリングされるときにデータをフェッチすることによって引き起こされます:
export default function Dashboard() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('/api/data')
.then(response => response.json())
.then(data => setData(data));
}, []);
return (
<div>
{data.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}
エフェクトでのフェッチは、データがより早くフェッチできたにもかかわらず、ユーザーがコンテンツを見るまでより長く待つ必要があることを意味します。
これを解決するために、TanStack Query、SWR、Apollo、Relayなどのデータフェッチライブラリを使用できます。これらはコンポーネントがレンダリングされる前にリクエストが開始されるようにデータをプリフェッチするオプションを提供します。
これらのライブラリは、ルートレベルでデータ依存関係を指定するルーティング「ローダー」パターンと統合されたときに最も効果的に動作し、ルーターがデータフェッチを最適化できるようになります:
export async function loader() {
const response = await fetch(`/api/data`);
const data = await response.json();
return data;
}
export default function Dashboard({ loaderData }) {
return (
<div>
{loaderData.map(item => <div key={item.id}>{item.name}</div>)}
</div>
)
}
初期読み込み時、ルーターはルートがレンダリングされる前にすぐにデータをフェッチできます。ユーザーがアプリ内を移動する際、ルーターはデータとルートの両方を同時にフェッチでき、フェッチを並列化できます。これにより、画面にコンテンツが表示されるまでの時間が短縮され、ユーザーエクスペリエンスが向上します。
しかし、これにはアプリでローダーを正しく設定する必要があり、パフォーマンスのために複雑さをトレードオフします。
コード分割
Create React Appでのもう一つの一般的な問題はコード分割です。Create React Appには特定のコード分割ソリューションが含まれていません。始めたばかりの場合、コード分割をまったく考慮しないかもしれません。これは、アプリが単一のバンドルとして出荷されることを意味します:
- bundle.js 75kb
しかし、理想的なパフォーマンスのためには、ユーザーが必要なもののみをダウンロードするように、コードを別々のバンドルに「分割」する必要があります。これにより、ユーザーが見ているページに必要なコードのみをダウンロードすることで、アプリの読み込み待機時間が短縮されます。
- core.js 25kb
- home.js 25kb
- dashboard.js 25kb
コード分割を行う一つの方法はReact.lazyを使用することです。しかし、これはコンポーネントがレンダリングされるまでコードがフェッチされないことを意味し、ネットワークウォーターフォールを引き起こす可能性があります。
より最適なソリューションは、コードのダウンロード中に並行してコードをフェッチするルーター機能を使用することです。例えば、React Routerは、ルートがコード分割され、読み込みタイミングを最適化することを指定するlazyオプションを提供します:
import Home from './Home';
import Dashboard from './Dashboard';
const router = createBrowserRouter([
{ path: '/', lazy: () => import('./Home') },
{ path: '/dashboard', lazy: () => import('Dashboard') }
]);
最適化されたコード分割は正しく行うのが困難で、ユーザーが必要以上のコードをダウンロードする原因となるミスを犯しやすいです。キャッシュの最大化、フェッチの並列化、「インタラクション時のインポート」パターンのサポートのために、ルーターとデータ読み込みソリューションと統合されたときに最も効果的に動作します。
その他...
これらはCreate React Appの制限のほんの一例です。ルーティング、データフェッチ、コード分割を統合すると、保留状態、ナビゲーションの中断、ユーザーへのエラーメッセージ、データの再検証も考慮する必要があります。
ユーザーが解決する必要がある問題のカテゴリ全体があります:
- アクセシビリティ
- アセット読み込み
- 認証
- キャッシュ
- エラーハンドリング
- データの変更
- ナビゲーション
- 楽観的更新
- プログレッシブエンハンスメント
- サーバーサイドレンダリング
- 静的サイト生成
- ストリーミング
これらすべてが連携して最も最適な読み込みシーケンスを作成します。Create React Appでこれらの問題を個別に解決することは困難です。各問題は他の問題と相互接続されており、ユーザーが馴染みのない問題領域での深い専門知識を必要とする場合があります。
これらの問題を解決するために、ユーザーはCreate React Appの上に独自の特注ソリューションを構築することになり、これはCreate React Appが元々解決しようとした問題でした。
フレームワークを推奨する理由
Create React App、Vite、Parcelなどのビルドツールでこれらすべての部分を自分で解決することもできますが、それは困難です。