Blog A.Wolf

Blog Posts

No results for 'undefined'Powered by Algolia

How to create a React app with-out using Create-React-App?

May 14th, 2019 - 5 min read

In this how to guide I'd like to explain how you can easily setup a React app from scratch with-out using Create React App (CRA)

But let me summarize the features we're having with this setup:

  • ES6 to ES5 transpilation (if req.) with @babel/preset-env (used by default from Parcel - so nothing to setup here)
  • JSX transpilation
  • Sass (just to show how it can be added)
  • CSS modules
  • Class properties supported
  • Hot reloading

Typescript support should be easy to add but not added here.

Step by step

Create new project

First create a new directory with mkdir your-new-project and cd your-new-project then inside the directory run yarn init -y to initialze your project. Next we can install our dependencies with yarn add react react-dom sass and yarn add @babel/core parcel-bundler @babel/plugin-proposal-class-properties @babel/preset-react -D to install the devDependencies.

Now you're having every dependency ready. Let's create our scripts and wire everything into the scripts section of the package.json file.

Setup & first project files

We can start by adding the following scripts & main entry to package.json:

  "main": "./public/index.html",
  "scripts": {
    "start": "parcel ./public/index.html --open",
    "build": "parcel build ./public/index.html"

To start the development server you can run yarn start and this will launch the devServer with hot reloading for us. build is creating the production files into dist directory.

So the basic setup is ready and we can add the missing files to have something we can render in the browser.

Create an index.html file with the following content in the folder public:

<!DOCTYPE html>
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Parcel example app</title>
    <div id="root"></div>
    <script src="../src/index.js">

Here we're adding the div where React will be rendered and the script tag with a relative path one level up because we're in folder public. The index.js is the entry point of our application and that's the next file we will add.

The index.js is your React app similar to the following code:

import React, { Component } from "react";
import ReactDOM from "react-dom";
import "./styles.css";
import styles from "./styles.scss";

class App extends Component {
  state = {
    message: "Hello from React",
    clickCount: 0

  incCounter = () => {
    this.setState(({ clickCount }) => ({
      clickCount: clickCount + 1

  render() {
    const { message, clickCount } = this.state;
    return (
      <div className={styles.message}>
        <p>clicked {clickCount}</p>
        <button onClick={this.incCounter}>Click me</button>

ReactDOM.render(<App />, document.getElementById("app"));

// Enable Hot Module Reloading
if ( {;

I think I don't have to go into every detail here. state = { } and incCounter are class properties and we need the Babel plugin @babel/plugin-proposal-class-properties to have them correctly handled.

The last line will enable hot reloading. So after saving your changes Parcel will rebuild your app and automatically reload the browser for you.

The Sass file is loaded by Parcel for us and you can access the imported style with styles.message because we have created a class named .message inside the file.

If you prefer to use css modules you have to add a .postcssrc and add the following configuration in it:

  "modules": true,

Then you can use the css file as a module like in the code snippet above. With-out postcss you could only load it with import "styles.css" and access the style with .message and add it with className="message".

For more details to the postcss setup you can have a look in the docs.

Start your server & check the result

With yarn start you launch the devServer and it will automatically open a browser window with your rendered app.

If everything is working as expected your app will look like in the following Codesandbox:


I think this setup is containing everything to get a basic React app up an running. Or am I missing an important feature of Create-React-App? But I think everything is available.

When would I use this setup? I think for small demos or when it's important to customize the setup. E.g. I'm trying to use it for an Electron app where I need to have Stylus for styling as the existing app relies on it. Adding Stylus to a Create-React-App is a bit hard and would probably require to eject. I think some customizations are possible with Parcel like adding Stylus. Anyway I think there are edge-cases where it's probably not possible or difficult to customize Parcel. But for now I'll give it a try.

For larger apps where you don't have to customize CRA I think it's OK to use. Even small customizations are possible either by ejecting or using react-app-rewired (which seems a bit out-dated & doesn't fully support CRA 2.x - so I wouldn't use it right now).

©2024 Alexander Wolf