【ITニュース解説】Using React Native Components in a Next.js Web App (via @expo/next-adapter)
2025年09月06日に「Dev.to」が公開したITニュース「Using React Native Components in a Next.js Web App (via @expo/next-adapter)」について初心者にもわかりやすく解説しています。
ITニュース概要
Next.jsでReact NativeのUI部品を使う方法を紹介。Expoのadapterで、コード共通化を可能にする。設定には、React Native Web、Tailwind CSS、Babelなどを使用。重要な点として、React Nativeの部品をtranspilePackagesに追加、Tailwind CSSのimport方法、CSS interop設定を行う必要がある。
ITニュース解説
この記事では、React Nativeで作成されたUIコンポーネントを、Next.jsで構築されたWebアプリケーションで再利用する方法について解説する。特に、@expo/next-adapterというライブラリを活用し、React Native Web、Tailwind CSS、NativeWind、react-native-css-interopといった技術を組み合わせることで、モバイルアプリとWebアプリ間でコードの重複を避けることを目指す。
まず、技術スタックとして、Next.js 15 (pages router)、React 19、React Native Web、Tailwind CSS v4、NativeWind v4、@expo/next-adapter、react-native-css-interop、Babelが挙げられている。これらの技術を組み合わせることで、React NativeのコンポーネントをWebブラウザ上でレンダリングすることが可能になる。
重要な点として、Tailwind CSS v4では、従来の@tailwind base; ...という記述ではなく、@import "tailwindcss";をglobals.cssで使用する必要がある。また、React Nativeのコンポーネントは、CSS interopなしではclassNameを理解しないため、View、Text、TouchableOpacity、Pressableといった基本的な要素に対してCSS interopを設定する必要がある。特に、Pressableは、多くのボタンやトリガーコンポーネントの基盤となっているため、必ず設定することが推奨される。
さらに、React Nativeや共有ライブラリをtranspilePackagesに追加する必要がある。これにより、Next.jsがこれらのパッケージをブラウザで実行可能なJavaScriptに変換し、構文エラーや実行時エラーを回避できる。Tailwind CSSのスタイルが他のスタイルシートよりも優先されるように、important: "html"を設定することも重要となる。
React Nativeライブラリを統合する手順は以下の通り。まず、ライブラリとその依存関係をインストールする。次に、ライブラリをtranspilePackagesに追加し、Next.jsがライブラリを変換できるようにする。そして、ライブラリ内のユーティリティクラスが生成されるように、ライブラリのパスをTailwind CSSのcontentに追加する。最後に、ライブラリがレンダリングする基本的な要素(View、Text、TouchableOpacity、Pressableなど)をCSS interopでカバーする。
具体的な設定例として、next.config.tsでは、withExpoを使用して設定を拡張し、transpilePackagesにReact Native関連のパッケージを追加する。webpackの設定では、react-native$をreact-native-webに、phosphor-react-nativeをphosphor-reactにエイリアスすることで、Web環境でのReact Nativeコンポーネントの解決を可能にする。
tsconfig.jsonでは、jsxImportSourceをnativewindに設定し、JSXの変換をNativeWindに委譲する。.babelrcでは、Babelのプリセットとプラグインを設定し、JSXの変換とReact Native Webのサポートを有効にする。tailwind.config.jsでは、Tailwind CSSの設定を行い、contentにReact Nativeライブラリのパスを追加し、important: "html"を設定する。postcss.config.mjsでは、Tailwind CSSのPostCSSプラグインを設定する。styles/globals.cssでは、@import "tailwindcss";を使用してTailwind CSSをインポートする。pages/_app.tsxでは、cssInteropを使用してReact Nativeの基本的な要素をスタイル付けできるようにする。
記事では、遭遇する可能性のある問題とその解決策も提示されている。例えば、背景色が表示されない場合は、Tailwind CSS v3のディレクティブがv4で使用されていることが原因である可能性がある。この場合、globals.cssで@import "tailwindcss";を使用する必要がある。また、ボーダーの幅は表示されるが、色が反映されない場合は、基盤となるコンポーネントがPressableであり、CSS interopが設定されていないことが原因である可能性がある。この場合、cssInterop(Pressable, { className: "style" })を設定する必要がある。node_modulesからの構文エラーが発生する場合は、React Nativeや共有ライブラリが変換されていないことが原因である可能性がある。この場合、transpilePackagesにこれらのパッケージを追加する必要がある。スタイルが上書きされる場合は、Tailwind CSSの設定でimportant: "html"を追加して、スタイルの優先度を上げる必要がある。
結論として、@expo/next-adapter、React Native Web、Tailwind CSS v4、NativeWind、react-native-css-interop、Babelを組み合わせることで、UIコードを重複させることなく、React NativeライブラリをNext.js Webアプリケーション内で利用可能になる。重要なステップは、React Nativeとライブラリを変換し、Tailwind CSS v4の@import CSSを使用し、ライブラリパスをTailwind CSSコンテンツに含め、classNameがスタイルに解決されるようにCSS interopでReact Nativeプリミティブ(Pressableを含む)をマッピングすることである。これらの手順を踏むことで、モバイルアプリとWebアプリで共通のUIコンポーネントを効率的に開発・管理することが可能になる。