OpenAIReactFeb 14, 2025, 12:00 AM

Sunsetting Create React App

A condensed section focused on the key takeaways first.

Original Post

Quick Digest

Summary

A condensed section focused on the key takeaways first.

openaienmodel: gpt-5-mini-2025-08-07

Sunsetting Create React App

Key Points

  • Create React App deprecated for new apps
  • Migrate to frameworks or Vite/Parcel/Rsbuild
  • CRA remains in maintenance mode with React 19 support

Summary

Create React App (CRA) is deprecated for new apps as of 2025-02-14. CRA will remain in maintenance mode (a new release supports React 19), but the React team recommends creating new projects with modern frameworks or migrating existing projects to frameworks or to build tools such as Vite, Parcel, or Rsbuild. The announcement adds a one-time deprecation console warning on new installs and documentation to help teams migrate or build custom setups from scratch.

Key Points

  • Deprecation & maintenance:

    • New installs of CRA show a one-time deprecation warning; CRA is now maintained with no active long-term maintainers.
    • CRA will continue to work for existing apps and has an update for React 19.
  • Recommended migration paths:

    • Prefer a framework (examples on react.dev) for most apps — frameworks integrate routing, data-loading, code-splitting, and deployment patterns out of the box.
    • If you prefer a custom setup, migrate to modern build tools: Vite, Parcel, or Rsbuild.
  • Migration resources provided:

    • Migration guides exist for Next.js, React Router, and Expo (frameworks), and for Vite/Parcel/Rsbuild (build-tool migrations).
    • New docs explain how to build a React app from scratch for learning or highly-customized constraints.
  • Why move off CRA:

    • CRA lacks integrated solutions for routing, data fetching, and optimized code-splitting; implementing these correctly is complex and easy to get wrong.
    • Frameworks provide built-in patterns (route-level loaders, parallel fetches, lazy-loading strategies) that improve performance and developer ergonomics.
  • Practical next steps for engineers:

    • For new apps: start with a framework that matches your rendering and deployment needs (CSR/SPA support, CDN/static deploy).
    • For existing apps: evaluate migrating to a framework first; if constraints require a bespoke toolchain, follow the build-tool migration guides for Vite/Parcel/Rsbuild.
    • Audit routing, data-fetching, and code-splitting in your app during migration; adopt route-level loaders or data libraries (e.g., TanStack Query/SWR) to avoid network waterfalls.

Full Translation

Translations

A translation section that keeps the flow of the original article.

openaijamodel: gpt-5-mini-2025-08-07

Create React App の廃止

2025年2月14日 — Matt Carroll と Ricky Hanlon

Create React App の廃止

本日、Create React App を新規アプリ向けに非推奨(deprecated)とし、既存アプリにはフレームワークへの移行、もしくは Vite、Parcel、RSBuild のようなビルドツールへの移行を推奨します。フレームワークがプロジェクトに合わない場合や、自分でフレームワークを作りたい場合、あるいは React をスクラッチから学びたい場合のためのドキュメントも公開しています。

背景

2016年に Create React App を公開した当時、新しい React アプリを作る明確な方法はありませんでした。JSX、lint、ホットリロードなどの基本機能をサポートするために多くのツールをインストールして自分で組み合わせる必要があり、正しく設定するのは非常に難しかったため、コミュニティは共通セットアップのためのボイラープレートを作成しました。しかし、ボイラープレートは更新が難しく、断片化により 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 のウェブサイトと GitHub リポジトリにも非推奨のお知らせを追加しました。Create React App はメンテナンスモードで動作し続け、React 19 と互換する新しいバージョンも公開済みです。

フレームワークへの移行方法

新しい React アプリはフレームワークで作成することを推奨します。推奨するフレームワークはすべてクライアントサイドレンダリング(CSR)とシングルページアプリ(SPA)をサポートし、サーバー無しで CDN や静的ホスティングへデプロイできます。

既存アプリをクライアント専用の SPA に移行する際のガイド例:

  • Next.js の Create React App 移行ガイド
  • React Router のフレームワーク導入ガイド
  • Expo (webpack から) → Expo Router 移行ガイド

ビルドツールへの移行方法

アプリに特殊な制約がある場合や、自分でフレームワークを作って問題を解決したい場合、あるいは React をスクラッチから学びたい場合は、Vite、Parcel、Rsbuild などのビルドツールでカスタムセットアップを作ることができます。

既存アプリをビルドツールへ移行する際のガイド例:

  • Vite Create React App migration guide
  • Parcel Create React App migration guide
  • Rsbuild Create React App migration guide

また、Vite、Parcel、Rsbuild を使って始めるための「Building a React App from Scratch」のドキュメントも追加しました。

深掘り

フレームワークは必要か?

ほとんどのアプリはフレームワークから恩恵を受けますが、スクラッチで React アプリを作るのが正当なケースもあります。経験則として、アプリにルーティングが必要ならフレームワークを利用した方が良いでしょう。Svelte に SvelteKit、Vue に Nuxt、Solid に SolidStart があるように、React でもデータフェッチやコード分割などと密に統合されたルーティングを提供するフレームワークを使うことを推奨します。自分で複雑な設定を書いて事実上フレームワークを作る手間を避けられます。

とはいえ、Vite、Parcel、Rsbuild のようなビルドツールを使ってスクラッチで React アプリを構築することも可能です。以下ではビルドツールの制約と、なぜフレームワークを推奨するかを説明します。

ビルドツールの制約

Create React App や同様のビルドツールは、React アプリを始めるのを簡単にします。npx create-react-app my-app を実行すると、開発サーバー、lint、プロダクションビルド付きのすぐに使える React アプリが手に入ります。たとえば内部管理ツールを作るとき、ランディングページから始められます:

export default function App() {
  return (
    <div>
      <h1>Welcome to the Admin Tool!</h1>
    </div>
  )
}

これにより JSX、デフォルトの lint ルール、開発・本番両方で動くバンドラーなどですぐにコーディングを始められます。しかし、このセットアップには本番アプリを構築するために必要なツールが欠けています。ほとんどのプロダクションアプリは、ルーティング、データフェッチ、コード分割のような問題への解決策を必要とします。

ルーティング

Create React App には特定のルーティングソリューションが含まれていません。始めたばかりなら useState でルートを切り替える方法もありますが、これではアプリへのリンクを共有できず、すべてのリンクが同じページに行ってしまいます。徐々にアプリ構造が難しくなります:

import { useState } from 'react';
import Home from './Home';
import Dashboard from './Dashboard';

export default function App() {
  // ❌ state によるルーティングは URL を作らない
  const [route, setRoute] = useState('home');
  return (
    <div>
      {route === 'home' && <Home />}
      {route === 'dashboard' && <Dashboard />}
    </div>
  )
}

このため、Create React App を使う多くのアプリは React Router や Tanstack Router のようなルーティングライブラリを追加してルーティングを実装します。ルーティングライブラリを使えば、アプリに追加のルートを加え、アプリの構造に対する意見(opinion)を提供し、ルートへのリンクを共有できるようになります。React Router の例:

import { RouterProvider, createBrowserRouter } from 'react-router';
import Home from './Home';
import Dashboard from './Dashboard';

// ✅ 各ルートに固有の URL がある
const router = createBrowserRouter([
  { path: '/', element: <Home /> },
  { path: '/dashboard', element: <Dashboard /> }
]);

export default function App() {
  return (
    <RouterProvider value={router} />
  )
}

ルーティングライブラリを導入すると、ネストされたルート、ルートガード、ルート遷移など、ライブラリなしでは実装が難しい機能を追加できます。ルーティングライブラリはアプリに複雑さを加えますが、それと引き換えに得られる機能は多くの場合有益です。

データフェッチ

Create React App には特定のデータフェッチソリューションは含まれていません。始めのうちはコンポーネント内の effect で fetch を使うことが一般的ですが、これだとコンポーネントが描画された後にデータを取りに行くため、ネットワークウォーターフォール(network waterfalls)を引き起こす可能性があります。ネットワークウォーターフォールは、コードのダウンロードと並列でデータを取得するのではなくレンダリング時にデータを取得することで発生します:

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>
  )
}

effect 内でフェッチすると、ユーザーがコンテンツを見るまでに余分な待ち時間が発生します。これを解決するには TanStack Query、SWR、Apollo、Relay などのデータフェッチライブラリを使い、プリフェッチやキャッシュを利用してリクエストをコンポーネント描画前に開始する方法があります。これらのライブラリはルーターの「loader」パターンと統合すると最も効果的で、ルートレベルでデータ依存関係を指定でき、ルーターがデータフェッチを最適化できます:

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 は特定のコード分割ソリューションを含んでいません。始めたばかりだとコード分割を全く考慮しないことがあります。その場合、アプリは単一バンドルとして配信されます:

  • bundle.js 75 kb

しかし理想的なパフォーマンスのためには、ユーザーが必要とするコードだけをダウンロードするようにコードを分割すべきです。これにより、ユーザーがページを見るまでの待ち時間を減らせます:

  • core.js 25 kb
  • home.js 25 kb
  • dashboard.js 25 kb

コード分割の一つの方法は 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') }
]);

最適化されたコード分割は正しく行うのが難しく、ユーザーが必要以上のコードをダウンロードしてしまうミスを起こしやすいです。ルーターやデータローディングと統合することで、キャッシュの最大化、フェッチの並列化、ユーザー操作時にインポートするパターン(import on interaction)をサポートするのが最も効果的です。

その他

ここで挙げたのは Create React App の制約のいくつかに過ぎません。ルーティング、データフェッチ、コード分割を統合した後は、ペンディング状態、ナビゲーションの中断、ユーザー向けのエラーメッセージ、データの再検証(revalidation)なども考慮する必要があります。ユーザーが解決すべき問題カテゴリは多数あります:

  • アクセシビリティ
  • アセット読み込み
  • 認証
  • キャッシュ
  • エラー処理
  • データの変更(ミューテーション)
  • ナビゲーション
  • 楽観的更新
  • プログレッシブエンハンスメント
  • サーバーサイドレンダリング
  • 静的サイト生成
  • ストリーミング

これらはすべて最適な読み込みシーケンスを作るために連携します。Create React App 上でこれらの問題を個別に解決するのは難しいことが多く、相互に関連しているため専門的な知識を要します。結果として、ユーザーは Create React App の上に独自のソリューションを構築することになりますが、それこそが Create React App が最初に解決しようとした問題でした。

なぜフレームワークを推奨するのか

Create React App、Vite、Parcel のようなビルドツールでこれらのすべてを自分で解決することもできますが、フレームワークはルーティング、データフェッチ、コード分割、キャッシュ戦略、ビルド最適化などを統合的に扱うことで、開発者が再発明する手間を減らし、プロダクション向けに最適化された経験を提供します。

(続き:元記事の意図と詳細ガイドへのリンクを参照してください。)

Sunsetting Create React App | React | DocsDigest