import { createRoot } from "react-dom/client";
import { App } from "./App";
const container = document.getElementById("app");
const root = createRoot(container)
root.render(<App />);
export function App() {
return <h1>Hello world!</h1>;
}
As you can see, we’ve referenced index.js
from a <script>
element in our HTML file. This imported react-dom
and used it to render our App
component into the <div id="app">
element in our page.
See Building a web app with Parcel for more details on getting started with a new project.
Parcel supports JSX automatically when it detects you are using React. If you’re using React 17 or later, it also automatically enables the modern JSX transform, which means you don't even need to import React for JSX to work, as you can see in App.js
in the above example.
To learn more about JSX, see Introducing JSX and JSX In Depth in the React docs, and the JSX section from Parcel's JavaScript docs for details on how you can configure some details of how it's handled.
Parcel has first-class support for React Fast Refresh, which gives you quick feedback as you edit your code without needing to reload the page. In most cases, it can preserve component state as code is edited, even if you make an error. See the Hot reloading docs for details on how this works.
createRoot
or they will be remounted on every change.For more tips, see the official React Fast Refresh docs.
TypeScript is supported out of the box. You can reference a .ts
or .tsx
file from your HTML page, and Parcel will compile it as you'd expect.
To add TypeScript definitions for React, install the following packages into your project:
yarn add @types/react @types/react-dom --dev
See the TypeScript docs for more details on using TypeScript with Parcel.
Flow is supported automatically when it is installed. To add it to an existing project, first install flow-bin
as a dependency:
yarn add flow-bin --dev
Then, use the // @flow
directive at the top of the files you'd like to type check. This also signals to Parcel which files can have Flow types that should be stripped when compiling for the browser.
See the Flow docs for more details on using Flow with Parcel.
Parcel supports many different ways of styling applications written with React.
You can import a CSS file into a JavaScript or TypeScript file to load it along with a component.
You can also load CSS using a standard <link rel="stylesheet">
element in your HTML file, but referencing CSS from your components helps make it clear which components depend on which CSS. This can also help with code splitting because only the CSS necessary for the components that you render will be loaded.
Parcel also supports CSS languages like SASS, Less, and Stylus. See CSS for more details on how CSS is processed by Parcel.
By default, CSS imported from JavaScript is global. If two CSS files define the same class names, they will potentially clash and overwrite each other. To solve this, Parcel supports CSS modules.
CSS modules treat the classes defined in each file as unique. Each class name is renamed to include a unique hash, and a map is exported to JavaScript to allow referencing these renamed class names.
To use CSS modules, create a file with the .module.css
extension, and import it from a JavaScript file with a namespace import. Then, you can use the exports of the CSS module when rendering elements in JSX.
See CSS modules to learn more about how Parcel handles CSS modules.
CSS-in-JS libraries like Styled Components, Emotion, and many others work well with Parcel. Some may require build configuration, such as a Babel plugin. To enable it, create a Babel configuration in your project and Parcel will pick it up automatically.
For example, to use Emotion, install the Babel plugin and create a .babelrc
in your project:
yarn add @emotion/babel-plugin --dev
yarn add @emotion/react
You’ll also need to set the jsxImportSource
option in a tsconfig.json
or jsconfig.json
so that Emotion's JSX pragma is used instead of the default one. This enables the css
prop to work.
Now, you can render elements with CSS-in-JS:
Tailwind CSS is a popular utility-first CSS framework. It uses PostCSS to build a CSS file containing only the classes you use in your code.
To use it, first, install the necessary dependencies:
yarn add tailwindcss postcss autoprefixer --dev
Next, create the config files needed for PostCSS and Tailwind. This example will use Tailwind’s JIT mode to speed up builds by only compiling the classes you use. Make sure you modify the glob passed to the content
option so it matches all of the source files where you'll use Tailwind classes.
Finally, you can reference Tailwind classes from any files that match the content
glob listed in tailwind.config.js
.
You can reference external images from JSX using the URL
constructor. Parcel also supports using query parameters to resize and convert images to a different format. It also handles image optimization, and includes a content hash in output filenames for long term browser caching.
See URL dependencies in the JavaScript docs for more details about this syntax, and the Image docs for more information about how Parcel handles images.
External SVG files can be referenced as described above. You can also import SVGs as React components which can be rendered directly in JSX.
First, install the @parcel/transformer-svg-react
plugin and add it to your .parcelrc
:
yarn add @parcel/transformer-svg-react --dev
Now, you can import SVGs from your component files and render them just like any other component.
The above example showed how to convert every SVG file to JSX, but you may want to be more selective in some cases. See Importing as a React component in the SVG docs for more details.
See the SVG docs for more about how Parcel transforms and optimizes SVG files.
Code splitting helps reduce initial page load size by lazily loading sections of your app. This can be accomplished by using the dynamic import()
syntax, along with React.lazy
.
This example lazily loads a Profile
component when a user clicks a button. When it sees the dynamic import()
, Parcel moves the Profile
component into a separate bundle from the Home
component and loads it on demand. React.lazy
handles turning this into a component, and Suspense
handles rendering a fallback while it is loading.
See the Code Splitting docs for more details about code splitting in Parcel, and Code Splitting in the React docs for more about Suspense
and React.lazy
.