Bootstrapping a React TypeScript project with Parcel
Tags: typescript, react, parcel
Published: 2018-09-07 08:11:39

---
title: Bootstrapping a React TypeScript project with Parcel
published: true
description: You can bootstrap a React TypeScript project with (almost) zero configuration.
tags: typescript, react, parcel 
---

With the [Parcel](https://parceljs.org) bundler, you can bootstrap a React TypeScript project with (almost) zero configuration.

First, create a folder, cd into it, initialize NPM, install parcel and your React dependencies:

```bash
mkdir react-number-game
cd react-number-game
npm init -y
npm i parcel-bundler --save-dev
npm i react react-dom @types/react @types/react-dom --save
mkdir src
```

Then, open your favorite code editor. Create a `index.html` file in your `src` directory. Modern editors like VSCode provide [Emmet](https://emmet.io) completion features. You can just enter a `!`, press the tab key and you get a basic html structure. Inside the body, add a root div element and a script tag with the reference to your entry `index.tsx` file:

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <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>React TypeScript App</title>
</head>
<body>
  <div id="root"></div>
  <script src="./index.tsx"></script>
</body>
</html>
```

Your minimal `index.tsx` file could look like this. There is no special TypeScript feature in there yet:

```jsx
import * as React from 'react'
import { Component } from 'react'
import { render } from 'react-dom'
// import './index.css'

class App extends Component {
  render() {
    return (<h1>Hello World!</h1>)
  }
}

render(<App />, document.getElementById('root'))
```

Finally, add a start command to your `package.json`:

```js
{
  "name": "react-number-game",
  "version": "1.0.0",
  "description": "A number game in React",    
  "scripts": {
    "start": "parcel src/index.html",
  },
  "author": "Lea Rosema",
  "license": "MIT",
  "devDependencies": {
    // ...
  },
  "dependencies": {
    // ...
  }
}
```

Then, you can start your application via `npm start`.


### Additional project configuration

#### Production Build

Add a build command to your `package.json` and run `npm run build`:

```js
{
  "scripts": {
    "build": "parcel build src/index.html",
  }
}
```

#### Deployment

If you are using GitHub, you can easily deploy to gh-pages using the `gh-pages` npm package. I also use `rimraf` package to clean up the dist folder before building:

```bash
npm i rimraf gh-pages -D
```
Add the following scripts to your `package.json`:

```js
{
  "scripts": {
    "build": "parcel build --public-url . src/index.html",
    "clean": "rimraf dist/index.html dist/src.*.css dist/src.*.js dist/src.*.map",
    "predeploy": "npm run clean -s && npm run build -s",
    "deploy": "gh-pages -d dist"
  }
}
```

The `--public-url .` parameter in the `build` step is important, because your project is deployed at `https://username.github.io/projectname/` and the script is included with a slash by default (eg `/src.0123abcdef.js`). That would result in a 404 error.


#### TypeScript

You might need additional TypeScript configuration. Though, the minimal example works without any configuration. You can generate a `tsconfig.json` via `node_modules/.bin/tsc --init`. A nice minimal `tsconfig.json` could look like this:

```js
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "jsx": "react"
  }
}
```

#### Autoprefixer

Install autoprefixer via `npm i autoprefixer -D` and add a `.postcssrc`:

```js
{
  "plugins": {
    "autoprefixer": {
      "grid": true
    }
  }
}
```

#### SCSS

Just add a `index.scss` file to your project and import it into your entry `index.tsx`. Parcel automatically installs the `node-sass` precompiler for you.


#### .gitignore

Parcel builds the dist files in the related output folders `dist` and also has a cache folder `.cache`. I would recommend to add them to your `.gitignore` file:

```
dist/index.html
dist/src.*.js
dist/src.*.css
dist/src.*.map
.cache
```

#### Result

See the resulting code at my [react-number-game](https://github.com/terabaud/react-number-game/) repository on GitHub.