From c3b487d6bd206367352a457b3aecfbbc4b07298b Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 16 Feb 2025 19:23:59 -0500 Subject: [PATCH 1/4] Rewrite "Create" page to improve explanations and recommendations --- src/content/learn/creating-a-react-app.md | 129 +++++++++++++++++++--- 1 file changed, 115 insertions(+), 14 deletions(-) diff --git a/src/content/learn/creating-a-react-app.md b/src/content/learn/creating-a-react-app.md index cf7359e45b2..88f213791f5 100644 --- a/src/content/learn/creating-a-react-app.md +++ b/src/content/learn/creating-a-react-app.md @@ -4,21 +4,43 @@ title: Creating a React App -If you want to build a new app or website with React, we recommend starting with a framework. +React can be used to build apps and websites in a variety of ways. Here's our recommendations for how to create a new React app. +## Ways to Use React {/*ways-to-use-react*/} + +React is flexible. You can use it to build full-stack apps with integrated client and server functionality, in standalone client apps that work with any backend or just a browser, or even add React to an existing page generated by a server. + +We've found that most React apps have similar needs for data fetching and routing, and benefit from performance patterns like code splitting. Because of this, we primarily **[recommend using a React-based framework](#bleeding-edge-react-frameworks)** as the best way to build a React app. These frameworks provide good defaults, integrate these features, and provide room to grow your app over time. (Similarly, other UI libraries also recommend integrated frameworks - Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart.) + +If you want a simpler setup or are learning, you can **[start from scratch](#start-from-scratch)** with a lighter project setup, and we have suggestions for common tools that will help get your app going the right way. + +To learn more about the different ways to use React, see [the overview of web app architectures](/learn/web-app-architectures) + + + +#### Do I Need a Server to Deploy a React App? {/*react-app-deployment*/} + +Deploying a React app depends on what tools you use to build the app and what kind of app you're building. + +If you've built a client-side Single Page Application or a static content site, you just need a place to upload and host the JS, HTML, and CSS files for your site, and it can fetch data from any server or API as needed. Single-page apps can be deployed to a [CDN](https://developer.mozilla.org/en-US/docs/Glossary/CDN) or static hosting service, and do not need to run an app server. This also means that Single-Page Apps do not need Node to run, and can work with backends written in any language. + +If your app uses Server-Side Rendering to generate pages, you'll need to deploy the application somewhere that can host your app server. SSR apps do need Node or another JS runtime to run React on the server. + +Note that **all of the full-stack frameworks on this page can also create standalone single-page apps that don't need an app server!** If you would like to enable features that require a server (like Server-Side Rendering), you can later opt-in on individual routes without rewriting your app, and just change how you deploy it. + + + + + ## Recommended React frameworks {/*bleeding-edge-react-frameworks*/} -These recommended frameworks support all the features you need to deploy and scale your app in production. They have integrated the latest React features and take advantage of React’s architecture. - -#### React frameworks do not require a server. {/*react-frameworks-do-not-require-a-server*/} +These recommended frameworks support all the features you need to deploy and scale your app in production. They have integrated the latest React features and take advantage of React’s architecture. -All the frameworks on this page can create single-page apps. Single-page apps can be deployed to a [CDN](https://developer.mozilla.org/en-US/docs/Glossary/CDN) or static hosting service and do not need a server. If you would like to enable features that require a server (like server side rendering), you can opt-in on individual routes without rewriting your app. - ### Next.js (App Router) {/*nextjs-app-router*/} @@ -55,7 +77,7 @@ If you're new to Expo, check out the [Expo tutorial](https://docs.expo.dev/tutor Expo is maintained by [Expo (the company)](https://expo.dev/about). Building apps with Expo is free, and you can submit them to the Google and Apple app stores without restrictions. Expo additionally provides opt-in paid cloud services. -## Other options {/*other-options*/} +### Other Frameworks {/*other-frameworks*/} There are other up-and-coming frameworks that are working towards our full stack React vision: @@ -96,20 +118,99 @@ Server Components and Suspense are React features rather than Next.js features. - +## Start From Scratch {/*start-from-scratch*/} + +If you are learning React, are not using JS in your backend, only need client-side functionality, or want to design your app configuration yourself, there are other options available for starting a React project from scratch. + +Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. The [frameworks we recommend](#bleeding-edge-react-frameworks) have built-in solutions for these problems. If you want to choose your own solutions, we have some recommendations for commonly-used tools. + +### Install a Build Tool {/*install-a-build-tool*/} + +The first step is to install a build tool like `vite`, `parcel`, or `rsbuild`. These build tools provide features to package and run source code, provide a development server for local development and a build command to deploy your app to a production server. + +#### Vite {/*vite*/} + +[Vite](https://vite.dev/) is a build tool that aims to provide a faster and leaner development experience for modern web projects. + + +npx create-vite@latest my-app --template react + + +Vite is opinionated and comes with sensible defaults out of the box. Vite has a rich ecosystem of plugins to support fast refresh, JSX, Babel/SWC, and other common features. See Vite's [React plugin](https://vite.dev/plugins/#vitejs-plugin-react) or [React SWC plugin](https://vite.dev/plugins/#vitejs-plugin-react-swc) and [React SSR example project](https://vite.dev/guide/ssr.html#example-projects) to get started. + +Vite is already being used as a build tool in one of our [recommended frameworks](/learn/creating-a-react-app): [React Router](https://reactrouter.com/start/framework/installation). + +#### Parcel {/*parcel*/} + +[Parcel](https://parceljs.org/) combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production applications. + + +npm install --save-dev parcel + + +Parcel supports fast refresh, JSX, TypeScript, Flow, and styling out of the box. See [Parcel's React recipe](https://parceljs.org/recipes/react/#getting-started) to get started. + +#### Rsbuild {/*rsbuild*/} + +[Rsbuild](https://rsbuild.dev/) is an Rspack-powered build tool that provides a seamless development experience for React applications. It comes with carefully tuned defaults and performance optimizations ready to use. + + +npx create-rsbuild --template react + + +Rsbuild includes built-in support for React features like fast refresh, JSX, TypeScript, and styling. See [Rsbuild's React guide](https://rsbuild.dev/guide/framework/react) to get started. + + +### Common Application Patterns {/*common-application-patterns*/} + +The build tools listed above start off with a client-only, single-page app (SPA), but don't include any further solutions for common functionality like routing, data fetching, or styling. + +The React ecosystem includes many tools for these problems. We've listed a few that are widely used as a starting point, but feel free to choose other tools if those work better for you. + +#### Routing {/*routing*/} + +Routing determines what content or pages to display when a user visits a particular URL. You need to set up a router to map URLs to different parts of your app. You'll also need to handle nested routes, route parameters, and query parameters. Routers can be configured within your code, or defined based on your component folder and file structures. + +Routers are a core part of modern applications, and are usually integrated with data fetching (including prefetching data for a whole page for faster loading), code splitting (to minimize client bundle sizes), and page rendering approaches (to decide how each page gets generated). + +We suggest using: + +- [React Router](https://reactrouter.com/start/framework/custom) +- [Tanstack Router](https://tanstack.com/router/latest) + + +#### Data Fetching {/*data-fetching*/} + +Fetching data from a server or other data source is a key part of most applications. Doing this properly requires handling loading states, error states, and caching the fetched data, which can be complex. + +Purpose-built data fetching libraries do the hard work of fetching and caching the data for you, letting you focus on what data your app needs and how to display it. These libraries are typically used directly in your components, but can also be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well. + +Note that fetching data directly in components can lead to slower loading times due to network request waterfalls, so we recommend prefetching data in loaders or on the server as much as possible! + +If you're fetching data from most backends or REST-style APIs, we suggest using: + +- [React Query](https://react-query.tanstack.com/) +- [SWR](https://swr.vercel.app/) +- [RTK Query](https://redux-toolkit.js.org/rtk-query/overview) + +If you're fetching data from a GraphQL API, we suggest using: + +- [Apollo](https://www.apollographql.com/docs/react) +- [Relay](https://relay.dev/) + + +### Improving Application Performance {/*improving-application-performance*/} -#### Do you recommend Vite? {/*do-you-recommend-vite*/} +The build tools listed above default to building single page apps (SPAs). SPAs can be simpler to start with, but can also lead to slower overall app performance due to loading large amounts of JS. -We provide several Vite-based recommendations. +To improve app performance, you can use additional [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). You can also implement code splitting to break your app into smaller bundles that can be loaded on demand and improve loading times. -React Router v7 is a Vite based framework which allows you to use Vite's fast development server and build tooling with a framework that provides routing and data fetching. Just like the other frameworks we recommend, you can build a SPA with React Router v7. +If you start from scratch, these patterns will require more work to implement yourself and can be harder to get right, and adopting them may require a more significant migration effort (which is why we recommend using frameworks as the default approach ). -We also recommend using Vite when [adding React to an existing project](/learn/add-react-to-an-existing-project), or [building a framework](/learn/building-a-react-framework). +See [Web App Architectures](/learn/web-app-architectures) to learn more about possible rendering strategies and other performance improvements, and how to apply these techniques without a framework. -Just like Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart, React recommends using a framework that integrates with build tools like Vite for new projects. - ----- From ab3fbb1e0f077f860721012554481167afe7d88f Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 16 Feb 2025 20:42:59 -0500 Subject: [PATCH 2/4] Clean up links and add "No CRA" note --- src/content/learn/creating-a-react-app.md | 37 ++++++++++++------- src/content/learn/installation.md | 6 +-- src/content/reference/rsc/directives.md | 4 +- .../reference/rsc/server-components.md | 2 +- src/content/reference/rsc/server-functions.md | 2 +- src/content/reference/rsc/use-client.md | 4 +- src/content/reference/rsc/use-server.md | 2 +- 7 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/content/learn/creating-a-react-app.md b/src/content/learn/creating-a-react-app.md index 88f213791f5..5a8f7fb6eb1 100644 --- a/src/content/learn/creating-a-react-app.md +++ b/src/content/learn/creating-a-react-app.md @@ -12,9 +12,9 @@ React can be used to build apps and websites in a variety of ways. Here's our re React is flexible. You can use it to build full-stack apps with integrated client and server functionality, in standalone client apps that work with any backend or just a browser, or even add React to an existing page generated by a server. -We've found that most React apps have similar needs for data fetching and routing, and benefit from performance patterns like code splitting. Because of this, we primarily **[recommend using a React-based framework](#bleeding-edge-react-frameworks)** as the best way to build a React app. These frameworks provide good defaults, integrate these features, and provide room to grow your app over time. (Similarly, other UI libraries also recommend integrated frameworks - Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart.) +We've found that most React apps have similar needs for data fetching and routing, and benefit from performance patterns like code splitting. Because of this, we primarily **[recommend using a React-based framework](#recommended-react-frameworks)** as the best way to build a React app. These frameworks provide good defaults, integrate these features, and provide room to grow your app over time. (Similarly, other UI libraries also recommend integrated frameworks - Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart.) -If you want a simpler setup or are learning, you can **[start from scratch](#start-from-scratch)** with a lighter project setup, and we have suggestions for common tools that will help get your app going the right way. +If you want a simpler setup or are learning, you can **[start from scratch](#start-from-scratch)** with a basic project, and we have suggestions for common tools that will help get your app going the right way. To learn more about the different ways to use React, see [the overview of web app architectures](/learn/web-app-architectures) @@ -30,31 +30,28 @@ If your app uses Server-Side Rendering to generate pages, you'll need to deploy Note that **all of the full-stack frameworks on this page can also create standalone single-page apps that don't need an app server!** If you would like to enable features that require a server (like Server-Side Rendering), you can later opt-in on individual routes without rewriting your app, and just change how you deploy it. - - -## Recommended React frameworks {/*bleeding-edge-react-frameworks*/} - - +## Recommended React frameworks {/*recommended-react-frameworks*/} These recommended frameworks support all the features you need to deploy and scale your app in production. They have integrated the latest React features and take advantage of React’s architecture. - ### Next.js (App Router) {/*nextjs-app-router*/} -**[Next.js's App Router](https://nextjs.org/docs) is a React framework that takes full advantage of React's architecture to enable full-stack React apps.** +**[Next.js's App Router](https://nextjs.org/docs) is a React framework that takes full advantage of React's architecture to enable full-stack React apps.** You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports [static export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) which doesn't require a server. + +To create a new Next.js project, run: npx create-next-app@latest -Next.js is maintained by [Vercel](https://vercel.com/). You can [deploy a Next.js app](https://nextjs.org/docs/app/building-your-application/deploying) to any Node.js or serverless hosting, or to your own server. Next.js also supports [static export](https://nextjs.org/docs/app/building-your-application/deploying/static-exports) which doesn't require a server. Vercel additionally provides opt-in paid cloud services. +Next.js is maintained by [Vercel](https://vercel.com/). Vercel additionally provides opt-in paid cloud services. ### React Router (v7) {/*react-router-v7*/} -**[React Router](https://reactrouter.com/start/framework/installation) is the most popular routing library for React and can be paired with Vite to create a full-stack React framework**. It emphasizes standard Web APIs and has several [ready to deploy templates](https://github.com/remix-run/react-router-templates) for various JavaScript runtimes and platforms. +**[React Router](https://reactrouter.com/start/framework/installation) is the most popular routing library for React. It can be paired with Vite to create a full-stack React framework**. It emphasizes standard Web APIs and has several [ready to deploy templates](https://github.com/remix-run/react-router-templates) for various JavaScript runtimes and platforms. To create a new React Router framework project, run: @@ -66,7 +63,9 @@ React Router is maintained by [Shopify](https://www.shopify.com). ### Expo (for native apps) {/*expo*/} -**[Expo](https://expo.dev/) is a React framework that lets you create universal Android, iOS, and web apps with truly native UIs.** It provides an SDK for [React Native](https://reactnative.dev/) that makes the native parts easier to use. To create a new Expo project, run: +**[Expo](https://expo.dev/) is a React framework that lets you create universal Android, iOS, and web apps with truly native UIs.** It provides an SDK for [React Native](https://reactnative.dev/) that makes the native parts easier to use. + +To create a new Expo project, run: npx create-expo-app@latest @@ -122,7 +121,17 @@ Server Components and Suspense are React features rather than Next.js features. If you are learning React, are not using JS in your backend, only need client-side functionality, or want to design your app configuration yourself, there are other options available for starting a React project from scratch. -Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. The [frameworks we recommend](#bleeding-edge-react-frameworks) have built-in solutions for these problems. If you want to choose your own solutions, we have some recommendations for commonly-used tools. +Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. The [frameworks we recommend](#recommended-react-frameworks) have built-in solutions for these problems. If you want to choose your own solutions, we have some recommendations for commonly-used tools. + + + +#### Should I use the legacy Create React App tool? {/*should-i-use-legacy-cra*/} + +**No. We have officially deprecated Create React App - please _do not_ use it!** The tools recommended on this page are faster, better maintained, and provide more features. + +For more information, see [Sunsetting Create React App](/blog/2025/02/14/sunsetting-create-react-app). + + ### Install a Build Tool {/*install-a-build-tool*/} @@ -212,6 +221,8 @@ See [Web App Architectures](/learn/web-app-architectures) to learn more about po + + ----- _If you’re a framework author interested in being included on this page, [please let us know](https://github.com/reactjs/react.dev/issues/new?assignees=&labels=type%3A+framework&projects=&template=3-framework.yml&title=%5BFramework%5D%3A+)._ \ No newline at end of file diff --git a/src/content/learn/installation.md b/src/content/learn/installation.md index f9a5b10fddd..9905176be34 100644 --- a/src/content/learn/installation.md +++ b/src/content/learn/installation.md @@ -34,11 +34,9 @@ To try React locally on your computer, [download this HTML page.](https://gist.g ## Creating a React App {/*creating-a-react-app*/} -If you want to start a new React app, you can [create a React app](/learn/creating-a-react-app) using a recommended framework. +If you want to start a new React app, you can [create a React app](/learn/creating-a-react-app#recommended-react-frameworks) using a recommended framework. -## Build a React Framework {/*build-a-react-framework*/} - -If a framework is not a good fit for your project, or you prefer to start by building your own framework, you can [build your own React framework](/learn/building-a-react-framework). +If a framework is not a good fit for your project, or you prefer to pick and choose your project's tools, you can [start from scratch](/learn/creating-a-react-app#start-from-scratch). ## Add React to an existing project {/*add-react-to-an-existing-project*/} diff --git a/src/content/reference/rsc/directives.md b/src/content/reference/rsc/directives.md index 42256de4958..a4983fdb856 100644 --- a/src/content/reference/rsc/directives.md +++ b/src/content/reference/rsc/directives.md @@ -4,13 +4,13 @@ title: Directives -Directives are for use in [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +Directives are for use in [React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). -Directives provide instructions to [bundlers compatible with React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +Directives provide instructions to [bundlers compatible with React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). diff --git a/src/content/reference/rsc/server-components.md b/src/content/reference/rsc/server-components.md index b58b7dea73a..858b5f0ab2d 100644 --- a/src/content/reference/rsc/server-components.md +++ b/src/content/reference/rsc/server-components.md @@ -4,7 +4,7 @@ title: Server Components -Server Components are for use in [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +Server Components are for use in [React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). diff --git a/src/content/reference/rsc/server-functions.md b/src/content/reference/rsc/server-functions.md index b079e322e69..b2632d0d5b2 100644 --- a/src/content/reference/rsc/server-functions.md +++ b/src/content/reference/rsc/server-functions.md @@ -4,7 +4,7 @@ title: Server Functions -Server Functions are for use in [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +Server Functions are for use in [React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). **Note:** Until September 2024, we referred to all Server Functions as "Server Actions". If a Server Function is passed to an action prop or called from inside an action then it is a Server Action, but not all Server Functions are Server Actions. The naming in this documentation has been updated to reflect that Server Functions can be used for multiple purposes. diff --git a/src/content/reference/rsc/use-client.md b/src/content/reference/rsc/use-client.md index fe6f5b1edb6..64c5cf15298 100644 --- a/src/content/reference/rsc/use-client.md +++ b/src/content/reference/rsc/use-client.md @@ -5,7 +5,7 @@ titleForTitleTag: "'use client' directive" -`'use client'` is for use with [React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +`'use client'` is for use with [React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). @@ -41,7 +41,7 @@ export default function RichTextEditor({ timestamp, text }) { } ``` -When a file marked with `'use client'` is imported from a Server Component, [compatible bundlers](/learn/start-a-new-react-project#bleeding-edge-react-frameworks) will treat the module import as a boundary between server-run and client-run code. +When a file marked with `'use client'` is imported from a Server Component, [compatible bundlers](/learn/start-a-new-react-project#recommended-react-frameworks) will treat the module import as a boundary between server-run and client-run code. As dependencies of `RichTextEditor`, `formatDate` and `Button` will also be evaluated on the client regardless of whether their modules contain a `'use client'` directive. Note that a single module may be evaluated on the server when imported from server code and on the client when imported from client code. diff --git a/src/content/reference/rsc/use-server.md b/src/content/reference/rsc/use-server.md index 4d6fb46397a..38178253714 100644 --- a/src/content/reference/rsc/use-server.md +++ b/src/content/reference/rsc/use-server.md @@ -5,7 +5,7 @@ titleForTitleTag: "'use server' directive" -`'use server'` is for use with [using React Server Components](/learn/start-a-new-react-project#bleeding-edge-react-frameworks). +`'use server'` is for use with [using React Server Components](/learn/start-a-new-react-project#recommended-react-frameworks). From 1838775bd3e46077c2c1e0638eb19af009e4fbfd Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 16 Feb 2025 20:48:16 -0500 Subject: [PATCH 3/4] Rename "Build a Framework" to "Web App Architecture" --- .../blog/2025/02/14/sunsetting-create-react-app.md | 8 ++++---- ...ding-a-react-framework.md => web-app-architectures.md} | 0 src/sidebarLearn.json | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/content/learn/{building-a-react-framework.md => web-app-architectures.md} (100%) diff --git a/src/content/blog/2025/02/14/sunsetting-create-react-app.md b/src/content/blog/2025/02/14/sunsetting-create-react-app.md index 531d9c9f697..432bff2a10e 100644 --- a/src/content/blog/2025/02/14/sunsetting-create-react-app.md +++ b/src/content/blog/2025/02/14/sunsetting-create-react-app.md @@ -11,7 +11,7 @@ February 14, 2025 by [Matt Carroll](https://twitter.com/mattcarrollcode) and [Ri -Today, we’re deprecating [Create React App](https://create-react-app.dev/) for new apps, and encouraging existing apps to migrate to a [framework](/learn/creating-a-react-app). We’re also providing docs for when a framework isn’t a good fit for your project, or you prefer to start by [building a framework](/learn/building-a-react-framework). +Today, we’re deprecating [Create React App](https://create-react-app.dev/) for new apps, and encouraging existing apps to migrate to a [framework](/learn/creating-a-react-app#recommended-react-frameworks). We’re also providing docs for when a framework isn’t a good fit for your project, or you prefer to [start from scratch](/learn/creating-a-react-app#start-from-scratch). @@ -56,9 +56,9 @@ For existing apps, these guides will help you migrate to a client-only SPA: Create React App will continue working in maintenance mode, and we've published a new version of Create React App to work with React 19. -If your app has unusual constraints, or you prefer to solve these problems by building your own framework, or you just want to learn how react works from scratch, you can roll your own custom setup with React using Vite, Parcel or Rsbuild. +If your app has unusual constraints, or you prefer to solve these problems by building your own framework, or you just want to learn how React works from scratch, you can roll your own custom setup with React using Vite, Parcel or Rsbuild. -To help users get started with Vite, Parcel or Rsbuild, we've published new docs for [Building a Framework](/learn/building-a-react-framework). Continue reading to learn more about the [limitations of Create React App](#limitations-of-create-react-app) and [why we recommend frameworks](#why-we-recommend-frameworks). +To help users get started with Vite, Parcel or Rsbuild, we've published new docs for [Starting from Scratch](/learn/creating-a-react-app#start-from-scratch). Continue reading to learn more about the [limitations of Create React App](#limitations-of-create-react-app) and [why we recommend frameworks](#why-we-recommend-frameworks). @@ -68,7 +68,7 @@ We provide several Vite-based recommendations. React Router v7 is a Vite based framework which allows you to use Vite's fast development server and build tooling with a framework that provides routing and data fetching. Just like the other frameworks we recommend, you can build a SPA with React Router v7. -We also recommend using Vite when [adding React to an existing project](/learn/add-react-to-an-existing-project), or [building a framework](/learn/building-a-react-framework). +We also recommend using Vite when [adding React to an existing project](/learn/add-react-to-an-existing-project), or [starting from scratch](/learn/creating-a-react-app#start-from-scratch). Just like Svelte has Sveltekit, Vue has Nuxt, and Solid has SolidStart, React recommends using a framework that integrates with build tools like Vite for new projects. diff --git a/src/content/learn/building-a-react-framework.md b/src/content/learn/web-app-architectures.md similarity index 100% rename from src/content/learn/building-a-react-framework.md rename to src/content/learn/web-app-architectures.md diff --git a/src/sidebarLearn.json b/src/sidebarLearn.json index 7471eb20cc0..42ddf4a5752 100644 --- a/src/sidebarLearn.json +++ b/src/sidebarLearn.json @@ -28,13 +28,13 @@ "title": "Creating a React App", "path": "/learn/creating-a-react-app" }, - { - "title": "Building a React Framework", - "path": "/learn/building-a-react-framework" - }, { "title": "Add React to an Existing Project", "path": "/learn/add-react-to-an-existing-project" + }, + { + "title": "Web App Architectures", + "path": "/learn/web-app-architectures" } ] }, From b562dfb6b761d5cab5c70f97c2e028980af204ff Mon Sep 17 00:00:00 2001 From: Mark Erikson Date: Sun, 16 Feb 2025 22:30:20 -0500 Subject: [PATCH 4/4] Construct new "Web App Architectures" page --- src/content/learn/creating-a-react-app.md | 37 +-- src/content/learn/web-app-architectures.md | 301 ++++++++++++++++----- 2 files changed, 229 insertions(+), 109 deletions(-) diff --git a/src/content/learn/creating-a-react-app.md b/src/content/learn/creating-a-react-app.md index 5a8f7fb6eb1..b741534e09a 100644 --- a/src/content/learn/creating-a-react-app.md +++ b/src/content/learn/creating-a-react-app.md @@ -83,45 +83,12 @@ There are other up-and-coming frameworks that are working towards our full stack - [TanStack Start (Beta)](https://tanstack.com/): TanStack Start is a full-stack React framework powered by TanStack Router. It provides a full-document SSR, streaming, server functions, bundling, and more using tools like Nitro and Vite. - [RedwoodJS](https://redwoodjs.com/): Redwood is a full stack React framework with lots of pre-installed packages and configuration that makes it easy to build full-stack web applications. - - -#### Which features make up the React team’s full-stack architecture vision? {/*which-features-make-up-the-react-teams-full-stack-architecture-vision*/} - -Next.js's App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive components in a single React tree. - -For example, you can write a server-only React component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components: - -```js -// This component runs *only* on the server (or during the build). -async function Talks({ confId }) { - // 1. You're on the server, so you can talk to your data layer. API endpoint not required. - const talks = await db.Talks.findAll({ confId }); - - // 2. Add any amount of rendering logic. It won't make your JavaScript bundle larger. - const videos = talks.map(talk => talk.video); - - // 3. Pass the data down to the components that will run in the browser. - return ; -} -``` - -Next.js's App Router also integrates [data fetching with Suspense](/blog/2022/03/29/react-v18#suspense-in-data-frameworks). This lets you specify a loading state (like a skeleton placeholder) for different parts of your user interface directly in your React tree: - -```js -}> - - -``` - -Server Components and Suspense are React features rather than Next.js features. However, adopting them at the framework level requires buy-in and non-trivial implementation work. At the moment, the Next.js App Router is the most complete implementation. The React team is working with bundler developers to make these features easier to implement in the next generation of frameworks. - - ## Start From Scratch {/*start-from-scratch*/} If you are learning React, are not using JS in your backend, only need client-side functionality, or want to design your app configuration yourself, there are other options available for starting a React project from scratch. -Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. The [frameworks we recommend](#recommended-react-frameworks) have built-in solutions for these problems. If you want to choose your own solutions, we have some recommendations for commonly-used tools. +Starting from scratch gives you more flexibility, but does require that you make choices on which tools to use for routing, data fetching, and other common usage patterns. It's a lot like building your own framework, instead of using a framework that already exists. The [frameworks we recommend](#recommended-react-frameworks) have built-in solutions for these problems. If you want to choose your own solutions, we have some recommendations for commonly-used tools. @@ -194,7 +161,7 @@ Fetching data from a server or other data source is a key part of most applicati Purpose-built data fetching libraries do the hard work of fetching and caching the data for you, letting you focus on what data your app needs and how to display it. These libraries are typically used directly in your components, but can also be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well. -Note that fetching data directly in components can lead to slower loading times due to network request waterfalls, so we recommend prefetching data in loaders or on the server as much as possible! +Note that fetching data directly in components can lead to slower loading times due to network request waterfalls, so we recommend prefetching data in router loaders or on the server as much as possible! This allows a page's data to be fetched all at once as the page is being displayed. If you're fetching data from most backends or REST-style APIs, we suggest using: diff --git a/src/content/learn/web-app-architectures.md b/src/content/learn/web-app-architectures.md index 50e34ff6536..73fbbc6add4 100644 --- a/src/content/learn/web-app-architectures.md +++ b/src/content/learn/web-app-architectures.md @@ -1,137 +1,290 @@ --- -title: Building a React Framework +title: Web App Architectures --- -If your app has constraints not well-served by existing frameworks, or you prefer to solve these problems yourself, you can build your own framework. +Different web apps have different needs. Learn the most common patterns and architectures to help build your app with great performance, and decide which tools and patterns work best for your project. - +## Application Architectures {/*application-architectures*/} -### Consider using an existing framework {/*you-should-probably-use-a-framework*/} +Modern web apps have a broad range of architecture designs, and the needs of each app can vary based on the intended features and target audience. -Building a framework is complex and requires extensive expertise across various domains. This complexity is not limited to React — it is a widespread challenge encountered by all UI libraries. Using an existing framework can save significant time and effort by allowing you to focus on building your application. Existing frameworks have tested, robust features and community support. +### Architecture Categories {/*architecture-categories*/} -For a list of recommended frameworks, check out [Creating a React App](/learn/creating-a-react-app). +Historically, most apps have been classified into three architectural categories: - +#### Multi-Page Apps {/*multi-page-apps*/} -Building a framework is a large undertaking that often requires expertise in many different areas. Understanding your goals and requirements before starting to build your own framework can help guide your development process and save a considerable amount of time. +Multi-Page Apps are the original pattern found on the web. This pattern typically involves a web app server that responds to requests by running calculations, fetching data from a database, and returning plain HTML. -For example, if you need to build a framework that integrates with a specific system or infrastructure, it's important to understand the features and limitations of those systems. Understanding your constraints can help guide your framework development process. +MPAs are fast to load, because the browser only has to process the HTML and CSS for display without needing to load and run much JS. However, they can take longer for individual user interactions, because every click or form submission requires sending a full request to the server and waiting for the new page to be sent back. -If you are building your own framework to learn, using popular tools like Vite and React Router can be a good starting point and let you focus on how to combine different tools to build a framework. +#### Single-Page Apps (SPA) {/*single-page-apps*/} -## Step 1: Install a build tool {/*step-1-install-a-build-tool*/} +A standard Single-Page App consists of static HTML, JS, and CSS files that are served to the client. The client loads the JS for the app, and the JS then renders and displays all of the content on the client, inside the browser. An SPA client typically relies on fetching data from a server API, usually with the data in JSON format. -The first step is to install a build tool like `vite`, `parcel`, or `rsbuild`. These build tools provide features to package and run source code, provide a development server for local development and a build command to deploy your app to a production server. +SPAs can provide faster user interactions, because they can immediately respond to user input. SPAs are simple to deploy, because they consist of static files that can be uploaded to a CDN or any other web server. The architecture can be simpler, because there's just the client code running in the browser, and no mixture of different rendering patterns. -### Vite {/*vite*/} +However, SPAs also can take longer for the initial load due to increased JS bundle sizes. Additionally, data fetching can require handling more loading states and may have more network waterfalls leading to slower loading times. -[Vite](https://vite.dev/) is a build tool that aims to provide a faster and leaner development experience for modern web projects. - -npm create vite@latest my-app -- --template react - +#### Static Site Generation (SSG) {/*static-site-generation*/} -Vite is opinionated and comes with sensible defaults out of the box. Vite has a rich ecosystem of plugins to support fast refresh, JSX, Babel/SWC, and other common features. See Vite's [React plugin](https://vite.dev/plugins/#vitejs-plugin-react) or [React SWC plugin](https://vite.dev/plugins/#vitejs-plugin-react-swc) and [React SSR example project](https://vite.dev/guide/ssr.html#example-projects) to get started. +Static sites involve generating plain HTML files from code and data sources at build time. This could include using Markdown files to create a blog, or fetching database entries to generate item pages for an ecommerce site. -Vite is already being used as a build tool in one of our [recommended frameworks](/learn/creating-a-react-app): [React Router](https://reactrouter.com/start/framework/installation). +Static sites load extremely fast, because the server just needs to return the HTML file that was requested. But, they would need additional JS to run on the client to add interactivity. -### Parcel {/*parcel*/} +### Rendering Strategies {/*rendering-strategies*/} -[Parcel](https://parceljs.org/) combines a great out-of-the-box development experience with a scalable architecture that can take your project from just getting started to massive production applications. +Another way to look at application architectures is to group them based on how each page gets rendered. - -npm install --save-dev parcel - +* **Single-page apps (SPA)** load a single HTML page and dynamically updates the page as the user interacts with the app. SPAs are fast and responsive, but they can have slower initial load times. SPAs are the default architecture for most build tools. + +* **Streaming Server-side rendering (SSR)** renders a page on the server and sends the fully rendered page to the client. SSR can improve performance, but it can be more complex to set up and maintain than a single-page app. Adding streaming of responses can speed up performance as well. See [Vite's SSR guide]( https://vite.dev/guide/ssr). + +* **Static site generation (SSG)** generates static HTML files for your app at build time. SSG can improve performance, but it can be more complex to set up and maintain than server-side rendering. + +* **React Server Components (RSC)** lets you mix build-time, server-only, and interactive components in a single React tree. RSC can improve performance because only the rendered output for parts of the page needs to be sent for the client, minimizing JS bundle size and network traffic. -Parcel supports fast refresh, JSX, TypeScript, Flow, and styling out of the box. See [Parcel's React recipe](https://parceljs.org/recipes/react/#getting-started) to get started. -### Rsbuild {/*rsbuild*/} +Your rendering strategies need to integrate with your router so apps built with your framework can choose the rendering strategy on a per-route level. This will enable different rendering strategies without having to rewrite your whole app. For example, the landing page for your app might benefit from being statically generated (SSG), while a page with a content feed might perform best with server-side rendering. -[Rsbuild](https://rsbuild.dev/) is an Rspack-powered build tool that provides a seamless development experience for React applications. It comes with carefully tuned defaults and performance optimizations ready to use. +Using the right rendering strategy for the right routes can improve app performance, as shown by scores on the [Core Web Vitals metrics](https://web.dev/explore/learn-core-web-vitals). This can include decreasing the time it takes for the first byte of content to be loaded ([Time to First Byte](https://web.dev/articles/ttfb)), the first piece of content to render ([First Contentful Paint](https://web.dev/articles/fcp)), and the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)). - -npx create-rsbuild --template react - +### Modern App Architectures {/*modern-app-architectures*/} -Rsbuild includes built-in support for React features like fast refresh, JSX, TypeScript, and styling. See [Rsbuild's React guide](https://rsbuild.dev/guide/framework/react) to get started. +In practice, today's web apps are often a mixture of all of those techniques. - +A single app codebase might do initial static site generation at build time to produce initial HTML files for most of the pages. It could then load React into each page on the client side to add more interactivity, providing faster loading time than a plain SPA but better interactivity than a plain SSG. Similarly, the same codebase could have some pages that let the server generate the initial HTML, then add React for the interactivity on the client side. Either way, once the initial page load happens, the app behaves more like an SPA as the user interacts and navigates. -#### Metro for React Native {/*react-native*/} +Some frameworks let you generate an initial set of static pages, then incrementally regenerate them over time or cache the results of a requested page for faster loading in the future. -If you'd like your framework to support React Native you'll need to use [Metro](https://metrobundler.dev/), the JavaScript bundler for React Native. Metro supports bundling for platforms like iOS and Android, but lacks many features when compared to Vite or Parcel. We recommend starting with Vite or Parcel unless your project requires React Native support. +Modern React frameworks let you mix and match these approaches, either by configuring which approach to use for a specific page, enabling or disabling features, or choosing to use only the client-side features of the framework to export an SPA that doesn't need an application server. - +If you're building a project from scratch, that usually limits you to client-side SPA functionality, because server-side functionality requires more specific integration work. -## Step 2: Build your framework {/*step-2-build-your-framework*/} -The build tool you select starts with a client-only, single-page app (SPA). While SPAs can be a good place to start, many SPAs will encounter problems as they grow. Frameworks can provide the scaffolding to solve these problems. Most frameworks will implement routing, code-splitting, different rendering strategies, and data-fetching. These features are interconnected. For example, if you use a router that only works on the client it could prevent you from implementing server-side rendering. The best frameworks provide a cohesive, consistent experience across these features for developers and users. +## Common Application Patterns {/*common-application-patterns*/} + +We've found that most React apps have similar needs for data fetching and routing, and benefit from performance patterns like code splitting. + +If you're using an existing React Framework, it includes solutions to these standard patterns already. If you're starting from scratch, you'll need to choose and configure libraries to solve these problems, which will take additional work. ### Routing {/*routing*/} -Routing determines what to display when a user visits a particular URL. You need to set up a router to map URLs to different parts of your app. You'll also need to handle nested routes, route parameters, and query parameters. Most modern routers use file-based routing. Routing can be integrated with other features like: +Routing determines what content or pages to display when a user visits a particular URL. You need to set up a router to map URLs to different parts of your app. You'll also need to handle nested routes, route parameters, and query parameters. Routers can be configured within your code, or defined based on your component folder and file structures. + +Routers are a core part of modern applications, and are usually integrated with data fetching (including prefetching data for a whole page for faster loading), code splitting (to minimize client bundle sizes), and page rendering approaches (to decide how each page gets generated). + +At a basic level, routing _could_ be as simple as having a `useState` to switch between routes. But doing this means that you can't share links to your app - every link would go to the same page - and structuring your app becomes difficult over time: + +```js +import {useState} from 'react'; + +import Home from './Home'; +import Dashboard from './Dashboard'; + +export default function App() { + // ❌ Routing in state does not create URLs + const [route, setRoute] = useState('home'); + return ( +
+ {route === 'home' && } + {route === 'dashboard' && } +
+ ) +} +``` + +Existing frameworks like Next, React Router v7, and Expo include built-in routing solutions. If you're starting from scratch, you'll need to add routing support yourself, with a library like [React Router](https://reactrouter.com/) or [Tanstack Router](https://tanstack.com/router/latest). With a routing library, you can add additional routes to the app, which provides opinions on the structure of your app, and allows you to start sharing links to routes. For example, with React Router you can define routes: + +```js +import {RouterProvider, createBrowserRouter} from 'react-router'; + +import Home from './Home'; +import Dashboard from './Dashboard'; + +// ✅ Each route has it's own URL +const router = createBrowserRouter([ + {path: '/', element: }, + {path: '/dashboard', element: } +]); + +export default function App() { + return ( + + ) +} +``` -* **Rendering strategies** to enable different rendering strategies on different routes, so you can introduce new strategies without having to rewrite your whole app. This can decrease the time it takes for the first byte of content to be loaded ([Time to First Byte](https://web.dev/articles/ttfb)), the first piece of content to be rendered ([First Contentful Paint](https://web.dev/articles/fcp)), and the largest visible content of the app to be rendered ([Largest Contentful Paint](https://web.dev/articles/lcp)). -* **Data fetching** to enable data fetching before the page loads on a route. This can prevent layout shifts ([Cumulative Layout Shift](https://web.dev/articles/cls)) and decrease the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)) -* **Code splitting** to reduce the JavaScript bundle size sent to the client and improve performance on underpowered devices. This can reduce the time it takes for the browser to respond to a user interaction ([First Input Delay](https://web.dev/articles/fid)) and the largest visible content of the app to be rendered ([Largest Contentful Paint](https://web.dev/articles/lcp)). +With this change, you can share a link to `/dashboard` and the app will navigate to the dashboard page . Once you have a routing library, you can add additional features like nested routes, route guards, and route transitions, which are difficult to implement without a routing library. -If you're not sure how to get started with routing, we recommend using [React Router](https://reactrouter.com/start/framework/custom) or [Tanstack Router](https://tanstack.com/router/latest). +There's a tradeoff being made here: the routing library adds complexity to the app, but it also adds features that are difficult to implement without it. -### Data-fetching {/*data-fetching*/} -Data-fetching is the process of fetching data from a server or other data source. You need to set up or create a data-fetching library to handle data retrieval from your server and manage the state of that data. You'll also need to handle loading states, error states, and caching data. Data fetching can be integrated with features like: -* **Routing** to enable data fetching to take place before page loads. This can improve how quickly a page loads and becomes visible to users ([Largest Contentful Paint](https://web.dev/lcp)) and reduce time it takes for your app to be interactive ([Time to Interactive](https://web.dev/tti)). -* **Rendering strategies** to prerender fetched data before it is sent to the client. This can reduce the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/lcp)). +### Data Fetching {/*data-fetching*/} + +Fetching data from a server or other data source is a key part of most applications. Doing this properly requires handling loading states, error states, and caching the fetched data, which can be complex. Integrating routing and data fetching is particularly important to prevent network waterfalls. In a SPA, if you fetch data during a component's initial render, the first data fetch is delayed until all code has loaded and components have finished rendering. This is commonly known as a waterfall: instead of fetching data at the same time as your code is loading, you need to first wait for your code to load before fetching data. To address these waterfalls, your app needs to fetch the data for each route in parallel with sending code to the browser. -Popular data fetching libraries that you can use as a part of your framework include [React Query](https://react-query.tanstack.com/), [SWR](https://swr.vercel.app/), [Apollo](https://www.apollographql.com/docs/react), and [Relay](https://relay.dev/). +React frameworks provide multiple forms of built-in data fetching functionality. This includes Server-Side Rendering to fetch initial data for a page, Server Actions, and React Server Components. These can help avoid network waterfalls. They also typically enable use of Suspense for managing display of loading states. -### Rendering strategies {/*rendering-strategies*/} +For data fetching on the client side, the basic approach would be to use `fetch` in an effect to load the data: -Since the build tool you select only support single page apps (SPAs) you'll need to implement other [rendering patterns](https://www.patterns.dev/vanilla/rendering-patterns) like server-side rendering (SSR), static site generation (SSG), and/or React Server Components (RSC). Even if you don't need these features at first, in the future there may be some routes that would benefit SSR, SSG or RSC. +```js +export default function Dashboard() { + const [data, setData] = useState(null); -* **Single-page apps (SPA)** load a single HTML page and dynamically updates the page as the user interacts with the app. SPAs are fast and responsive, but they can have slower initial load times. SPAs are the default architecture for most build tools. + // ❌ Fetching data in a component causes network waterfalls + useEffect(() => { + fetch('/api/data') + .then(response => response.json()) + .then(data => setData(data)); + }, []); -* **Streaming Server-side rendering (SSR)** renders a page on the server and sends the fully rendered page to the client. SSR can improve performance, but it can be more complex to set up and maintain than a single-page app. With the addition of streaming, SSR can be very complex to set up and maintain. See [Vite's SSR guide]( https://vite.dev/guide/ssr). + return ( +
+ {data.map(item =>
{item.name}
)} +
+ ) +} +``` -* **Static site generation (SSG)** generates static HTML files for your app at build time. SSG can improve performance, but it can be more complex to set up and maintain than server-side rendering. +However, writing your own fetching logic and managing loading states quickly becomes unmaintainable. + +If you do need to fetch data on the client, there are purpose-built data fetching libraries that [do the hard work of fetching and caching the data for you](https://tkdodo.eu/blog/why-you-want-react-query), letting you focus on what data your app needs and how to display it. These libraries are typically used directly in your components, but can also be integrated into routing loaders for faster pre-fetching and better performance, and in server rendering as well. + +Even with these data fetching libraries, note that fetching data directly in components can lead to slower loading times due to network request waterfalls, where parent components fetch data, render children, and then the children fetch additional data. This is slow because the requests happen in sequence. Because of that, we recommend prefetching data in router loaders or on the server as much as possible! This allows a page's data to be fetched all at once as the page is being displayed. + + + +### Code Splitting {/*code-splitting*/} + +Code-splitting is the process of breaking your app into smaller bundles that can be loaded on demand. An app's code size increases with every new feature and additional dependency. Apps can become slow to load because all of the code for the entire app needs to be sent before it can be used. + +If you're just getting started, you might not consider code splitting at all. + +This means your app is shipped as a single bundle: + +```txt +- bundle.js 75kb +``` + +But for ideal performance, you should "split" your code into separate bundles so the user only needs to download what they need. This decreases the time the user needs to wait to load your app, by only downloading the code they need to see the page they are on. + +```txt +- core.js 25kb +- home.js 25kb +- dashboard.js 25kb +``` + +Build tools have basic support for code splitting, usually by looking for `import()` statements to identify where to split into separate files. + +One way to do code-splitting is with `React.lazy`. However, this means that the code is not fetched until the component renders, which can cause network waterfalls. A more optimal solution is to use a router feature that fetches the code in parallel while the code is downloading. For example, React Router provides a `lazy` option to specify that a route should be code split and optimize when it is loaded: + +```js +import Home from './Home'; +import Dashboard from './Dashboard'; + +// ✅ Routes are downloaded before rendering +const router = createBrowserRouter([ + {path: '/', lazy: () => import('./Home')}, + {path: '/dashboard', lazy: () => import('Dashboard')} +]); +``` + +Modern React frameworks that integrate build tools and routing can automatically do code splitting for you. + +Splitting code by route, when integrated with bundling and data fetching, can reduce the initial load time of your app and improve CWV metrics like the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)). + + +## Why We Recommend Frameworks {/*why-we-recommend-frameworks*/} + +Although you could solve all these pieces yourself in a build tool like Create React App, Vite, or Parcel, it is hard to do well. Just like when Create React App itself integrated several build tools together, you need a tool to integrate all of these features together to provide the best experience to users. + +This category of tools that integrates build tools, rendering, routing, data fetching, and code splitting are known as "frameworks" -- or if you prefer to call React itself a framework, you might call them "metaframeworks". + +Frameworks impose some opinions about structuring your app in order to provide a much better user experience, in the same way build tools impose some opinions to make tooling easier. This is why we started recommending frameworks like [Next.js](https://nextjs.org/), [React Router](https://reactrouter.com/), and [Expo](https://expo.dev/) for new projects. + +Frameworks provide the same getting started experience as Create React App, but also provide solutions to problems users need to solve anyway in real production apps. + +## Architecture Considerations {/*architecture-considerations*/} + +There are many factors that go into deciding the right architecture(s) for each application. Here are some important points to take into consideration. + +### Application Types {/*application-types*/} + +One way to approach deciding on the right architectures is to look at the kind of application you are building. + +The post [Application Holotypes: A Guide to Architecture Decisions](https://jasonformat.com/application-holotypes/) describes a spectrum of applications, each with their own variation of architectural needs. For example, a social media app might work well as a Single Page App, whereas an ecommerce site might benefit from a Server-Side Rendering architecture with some client interactivity. + +The [Patterns.dev guide on rendering and architectural patterns](https://www.patterns.dev/vanilla/rendering-patterns) also gives excellent insight into the different architectural techniques available and when to apply them. + +### Server rendering is optional {/*server-rendering-is-optional*/} + +The frameworks we recommend all provide the option to create a [client-side rendered (CSR)](https://developer.mozilla.org/en-US/docs/Glossary/CSR) app. + +In some cases, CSR is the right choice for a page, but many times it's not. Even if most of your app is client-side, there are often individual pages that could benefit from server rendering features like [static-site generation (SSG)](https://developer.mozilla.org/en-US/docs/Glossary/SSG) or [server-side rendering (SSR)](https://developer.mozilla.org/en-US/docs/Glossary/SSR), for example a Terms of Service page, or documentation. + +Server rendering generally sends less JavaScript to the client, and a full HTML document which produces a faster [First Contentful Paint (FCP)](https://web.dev/articles/fcp) by reducing [Total Blocking Time (TBD)](https://web.dev/articles/tbt), which can also lower [Interaction to Next Paint (INP)](https://web.dev/articles/inp). This is why the [Chrome team has encouraged](https://web.dev/articles/rendering-on-the-web) developers to consider static or server-side render over a full client-side approach to achieve the best possible performance. + +There are tradeoffs to using a server, and it is not always the best option for every page. Generating pages on the server incurs additional cost and takes time to generate which can increase [Time to First Byte (TTFB)](https://web.dev/articles/ttfb). The best performing apps are able to pick the right rendering strategy on a per-page basis, based on the tradeoffs of each strategy. + +Frameworks provide the option to use a server on any page if you want to, but do not force you to use a server. This allows you to pick the right rendering strategy for each page in your app. + + + +### Server Rendering is not just for SEO {/*server-rendering-is-not-just-for-seo*/} + +A common misunderstanding is that server rendering is only for [SEO](https://developer.mozilla.org/en-US/docs/Glossary/SEO). + +While server rendering can improve SEO, it also improves performance by reducing the amount of JavaScript the user needs to download and parse before they can see the content on the screen. + +This is why the Chrome team [has encouraged](https://web.dev/articles/rendering-on-the-web) developers to consider static or server-side render over a full client-side approach to achieve the best possible performance. + +### What About Server Components? {/*server-components*/} + +The frameworks we recommend also include support for React Server Components. + +Server Components help solve these problems by moving routing and data fetching to the server, and allowing code splitting to be done for client components based on the data you render, instead of just the route rendered, and reducing the amount of JavaScript shipped for the best possible [loading sequence](https://www.patterns.dev/vanilla/loading-sequence). + +Server Components do not require a server. They can be run at build time on your CI server to create a static-site generated app (SSG) app, at runtime on a web server for a server-side rendered (SSR) app. + +See [Introducing zero-bundle size React Server Components](/blog/2020/12/21/data-fetching-with-react-server-components) and [the docs](/reference/rsc/server-components) for more info. -* **React Server Components (RSC)** lets you mix build-time, server-only, and interactive components in a single React tree. RSC can improve performance, but it currently requires deep expertise to set up and maintain. See [Parcel's RSC examples](https://github.com/parcel-bundler/rsc-examples). -Your rendering strategies need to integrate with your router so apps built with your framework can choose the rendering strategy on a per-route level. This will enable different rendering strategies without having to rewrite your whole app. For example, the landing page for your app might benefit from being statically generated (SSG), while a page with a content feed might perform best with server-side rendering. Using the right rendering strategy for the right routes can decrease the time it takes for the first byte of content to be loaded ([Time to First Byte](https://web.dev/articles/ttfb)), the first piece of content to render ([First Contentful Paint](https://web.dev/articles/fcp)), and the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)). -### Code-splitting {/*code-splitting*/} +### Which features make up the React team’s full-stack architecture vision? {/*which-features-make-up-the-react-teams-full-stack-architecture-vision*/} -Code-splitting is the process of breaking your app into smaller bundles that can be loaded on demand. An app's code size increases with every new feature and additional dependency. Apps can become slow to load because all of the code for the entire app needs to be sent before it can be used. Caching, reducing features/dependencies, and moving some code to run on the server can help mitigate slow loading but are incomplete solutions that can sacrifice functionality if overused. +Next.js's App Router bundler fully implements the official [React Server Components specification](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). This lets you mix build-time, server-only, and interactive components in a single React tree. -Similarly, if you rely on the apps using your framework to split the code, you might encounter situations where loading becomes slower than if no code splitting were happening at all. For example, [lazily loading](/reference/react/lazy) a chart delays sending the code needed to render the chart, splitting the chart code from the rest of the app. [Parcel supports code splitting with React.lazy](https://parceljs.org/recipes/react/#code-splitting). However, if the chart loads its data *after* it has been initially rendered you are now waiting twice. This is a waterfall: rather than fetching the data for the chart and sending the code to render it simultaneously, you must wait for each step to complete one after the other. +For example, you can write a server-only React component as an `async` function that reads from a database or from a file. Then you can pass data down from it to your interactive components: -Splitting code by route, when integrated with bundling and data fetching, can reduce the initial load time of your app and the time it takes for the largest visible content of the app to render ([Largest Contentful Paint](https://web.dev/articles/lcp)). +```js +// This component runs *only* on the server (or during the build). +async function Talks({ confId }) { + // 1. You're on the server, so you can talk to your data layer. API endpoint not required. + const talks = await db.Talks.findAll({ confId }); -### And more... {/*and-more*/} + // 2. Add any amount of rendering logic. It won't make your JavaScript bundle larger. + const videos = talks.map(talk => talk.video); -These are just a few examples of the features a framework will need to consider. + // 3. Pass the data down to the components that will run in the browser. + return ; +} +``` -There are many other problems that users need to solve like: +Next.js's App Router also integrates [data fetching with Suspense](/blog/2022/03/29/react-v18#suspense-in-data-frameworks). This lets you specify a loading state (like a skeleton placeholder) for different parts of your user interface directly in your React tree: -- Accessibility -- Asset loading -- Authentication -- Error handling -- Mutating data -- Navigations -- Nested routes -- Optimistic updates -- Caching -- Progressive enhancement -- Static site generation -- Server-side rendering +```js +}> + + +``` -Many of these problems individually can be difficult as each problem is interconnected with the others and can require deep expertise in problem areas you may not be familiar with. If you don't want to solve these problems on your own, you can [get started with a framework](/learn/creating-a-react-app) that provides these features out of the box. +Server Components and Suspense are React features rather than Next.js features. However, adopting them at the framework level requires buy-in and non-trivial implementation work. At the moment, the Next.js App Router is the most complete implementation. The React team is working with bundler developers to make these features easier to implement in the next generation of frameworks.