DEV Community

Lea Rosema (she/her)
Lea Rosema (she/her)

Posted on • Updated on

Bootstrapping a React TypeScript project with Parcel

With the Parcel 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:

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
Enter fullscreen mode Exit fullscreen mode

Then, open your favorite code editor. Create a index.html file in your src directory. Modern editors like VSCode provide Emmet 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:

<!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>
Enter fullscreen mode Exit fullscreen mode

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

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'))
Enter fullscreen mode Exit fullscreen mode

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

{
  "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": {
    // ...
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

{
  "scripts": {
    "build": "parcel build src/index.html",
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

npm i rimraf gh-pages -D
Enter fullscreen mode Exit fullscreen mode

Add the following scripts to your package.json:

{
  "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"
  }
}
Enter fullscreen mode Exit fullscreen mode

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:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "strict": true,
    "jsx": "react"
  }
}
Enter fullscreen mode Exit fullscreen mode

Autoprefixer

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

{
  "plugins": {
    "autoprefixer": {
      "grid": true
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Result

See the resulting code at my react-number-game repository on GitHub.

Top comments (7)

Collapse
 
robertcoopercode profile image
Robert Cooper

Wow, it's much easier to get started using typescript with React than I thought!

Collapse
 
chiangs profile image
Stephen Chiang

I haven't tried this yet, but I know that my colleague was having to deal with really long compile times with this React-TypeScript project. Coming from Angular, I'm used to a couple seconds of live refresh time, but I just see him sitting there ready to pull his hair out and his dev time seriously cut. Do you experience any such phenomena with Parcel?

Collapse
 
misterhtmlcss profile image
Roger K.

Just a thought Lea, but you may want to add the tag "Parcel" to you blog post. I follow parcel posts and just about missed this one. ;)
Just a suggestion

Collapse
 
learosema profile image
Lea Rosema (she/her)

Thank you! I added the tag :)

Collapse
 
smartmind25 profile image
smartmind25

Nice

Collapse
 
dimpiax profile image
Dmytro Pylypenko

Parcel is fast and "zero-config" bundler.

Thanks for the post Lea. Did you try parcel-plugin-typescript?

Collapse
 
lukegibson profile image
Luke Gibson

How would you get this project set up with TSlint?