Material-UI: Get started (Fast!) ⚡ React 16+
Tags: react, javascript, node, webdev
Published: 2018-04-14 23:34:29

---
cover_image: https://thepracticaldev.s3.amazonaws.com/i/f8nsdb0yufu95c8pzhjp.png
title: Material-UI: Get started (Fast!) ⚡ React 16+
published: true
description: How to get started with Material-UI using React 16+? This is my Step-By-Step guide that will show you the easy and the right way. Believe me! I’ve tested a bunch of solutions (so you don’t have to). These are the proven instructions to use Material-UI in 2018 and beyond.
tags: React, JavaScript, Node, WebDev
---

How to get started with Material-UI?

Here is the easy and the right way in my opinion.

Just go and follow the [instructions](https://github.com/kireerik/razzle-material-ui-styled-example#getting-started) right here:

{% github kireerik/razzle-material-ui-styled-example %}

> Wait! Are you on some kind of Unix based system? Mac? Linux? If so you might want to change the `PORT` within the [`.env`](https://github.com/kireerik/razzle-material-ui-styled-example/blob/6ad048dbb9fb6565070c9bd48bb0617a052b2572/.env#L2) file, which I have set to `80` which works on Windows. [Razzle](https://github.com/jaredpalmer/razzle)'s default is `3000` so you can remove that line if you feel like it.

The project is up and running.

![development mode](https://thepracticaldev.s3.amazonaws.com/i/umu057rj5xoq0j7q0f5h.gif)

Go wild and experiment!

I am not joking. Close this article right now and try the project instead!

Just kidding! 😄 You can read on later...

> Are you lazy? [Start the project on Codenvy](https://codenvy.io/dashboard/#/load-factory?id=factoryffyherfcfvcdm83r) instead! One click and the project is up and running after login.

Are you still reading? All right, I will hold your hand and walk you through it.

## Usage
Things will get boring here. I have told you to try it yourself instead.

All right, jokes aside. We are getting serious here.
### Basic

![folder structure](https://thepracticaldev.s3.amazonaws.com/i/x569tgx1153ux0mgd53o.png)

Folder structure
- public ⬅Static files are here.
- src
	- _application/**[Main.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/application/Main.js)**_ ⬅The main React.js component.
	- ***[server.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/server.js)*** ⬅Serves the minified HTML.
	- client.js, index.js, static.js ⬅"Lower level" scripts (will discuss later).

As you may already figured out. The `Main.js` contains the React.js component. So basically you can change the main content of your site [here](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/application/Main.js#L47-L55).

<p><img src="https://thepracticaldev.s3.amazonaws.com/i/1k1kehgi3glmbar37m0p.png" 
alt="source code" width="258" height="208"></p>

The `server.js` [renders the React.js application, collects the styles](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/server.js#L30), and serves all of this content as HTML when you visit the site.

Inspect the source code! Yes, the dream came true. It is a properly minified one-liner. You can [modify your main HTML here](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/server.js#L34-L56), mainly your header.

> [How to actually start the project](https://github.com/kireerik/razzle-material-ui-styled-example#getting-started) is detailed in the already linked readme. [Features](https://github.com/kireerik/razzle-material-ui-styled-example#features) of the example project are listed there too.

#### 📝 Code
Styling components in `Main.js` is this easy with [Styled Components](https://www.styled-components.com/):
```javascript
import styled from 'styled-components'

const Div = styled.div`
	text-align: center;
`

export const Main = () => <Div></Div>
```

This is how Server Side Rendering works with Styled Components in `server.js`:
```javascript
import {renderToString} from 'react-dom/server'
import {ServerStyleSheet} from 'styled-components'

import Application from './application/Main'

const sheet = new ServerStyleSheet()
, html = renderToString(sheet.collectStyles(<Application />))
, css = sheet.getStyleTags()

// server response to send:
	`<!DOCTYPE HTML>
	<html lang="en">
		<head>` + css + `</head>
		<body>
			<div id="root">` + html + `</div>
		</body>
	</html>`
```
It also includes some extra, like [compression for static resources](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/server.js#L26-L27) and HTML minification:
```javascript
import {minify} from 'html-minifier'

minify(
	`<!DOCTYPE HTML><html lang="en">...</html>`
, {
	collapseWhitespace: true
	, removeComments: true
	, minifyCSS: true
	, minifyJS: true
})
```

### Advanced
The `src/index.js` is the main entry point for the **server**. This is required by Razzle.

The `src/client.js` is the main entry point for the **browser**. This is also required by Razzle.

The optional `.env` contains some environment variable definitions.

You can find the build scripts in `package.json` under the `scripts` object.

#### 📝 Code
This is how the main entry point (`index.js`) starts the server (`server.js`):
```javascript
import express from 'express'
import server from './server'

export default express()
	.use((request, response) => server.handle(request, response))
	.listen(process.env.PORT)
```
Here is the full [simplest version of index.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/d85a4f762220cfd33d45797f192858307b288d4e/src/index.js).

The [client.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/client.js) entry point hydrates the already rendered application in the browser:
```javascript
import {hydrate} from 'react-dom'

import Application from './application/Main'

hydrate(<Application />, document.getElementById('root'))
```

In [package.json](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/package.json#L2-L7), the `start` script is using a build and run approach:
```json
{
	"scripts": {
		"start": "razzle build && cross-env NODE_ENV=production node build/server.js"
	}
}
```

![yarn start.gif](https://thepracticaldev.s3.amazonaws.com/i/ac6c8kl2xu1vals19v7u.gif)

#### Material-UI
Server Side Rendering makes it a bit more complex to use Material-UI properly. Setting the `userAgent` is not necessarily straightforward (at least for me). However, the [documentation](http://www.material-ui.com/#/get-started/server-rendering) is not that bad.

The following codes with the links are hopefully giving some context:
[server.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/server.js#L30):
```javascript
renderToString(<Application userAgent={request.headers['user-agent']} />)
```

[client.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/client.js#L6):
```javascript
hydrate(<Application userAgent={navigator.userAgent} />, document.getElementById('root'))
```

[Main.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/application/Main.js#L29):
```javascript
class Main extends Component {
	constructor(properties) {
		super(properties)

		this.muiTheme = getMuiTheme({
			userAgent: properties.userAgent
		})
	}

	render = () =>
		<MuiThemeProvider muiTheme={this.muiTheme}></MuiThemeProvider>
}
```

> [Read this solution on Stack Overflow](https://stackoverflow.com/questions/37816998/react-server-side-rendering-with-express-warning-on-the-client-checksum-styl/43958663#43958663) and press the vote up button if you find it useful too.

#### Single route static site generation
The optional [static.js](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/static.js) is [called from the main server entry point](https://github.com/kireerik/razzle-material-ui-styled-example/blob/master/src/index.js#L25) (`index.js`). It grabs the already generated static resources and copies them into the `static` folder. Plus it visits the URL and saves the HTML response:
```javascript
import http from 'http'
import fs from 'fs-extra'

const staticDirectory = process.env.RAZZLE_STATIC_PATH || 'static'

http.get({url: 'http://' + process.env.HOST + ':' + process.env.PORT
	, headers: {'User-Agent': 'all'}
}, response =>
	response.on('data', html =>
		fs.writeFile(staticDirectory + '/' + 'index.html', html)
	)
)
```

![static site generation](https://thepracticaldev.s3.amazonaws.com/i/81237x87taxesjq8lfqw.gif)

The static site generation script is somewhat complex:
```json
{
	"scripts": {
		"static": "cross-env RAZZLE_STATIC=true razzle build && cross-env NODE_ENV=production node build/server.js"
	}
}
```
1. A regular Razzle build is created with the static setting (`RAZZLE_STATIC=true`) baked into the generated server side code.
2. This build is started in `production` mode.
3. The static generator is only executed this time. It performs the steps described before and closes the server.

## About the example

### Motivation
I wanted to create a more current and appealing version of [Search is Back!](https://searchisback.com/). Why? Because I thought I could do it better and I still think I can.
I quickly realized that I will need to combine a couple of technologies to implement my vision.
> So "...after testing a bunch of example projects, I ended up finding and using Razzle." ([source](https://github.com/jaredpalmer/razzle/issues/289#issuecomment-306586593))

I also needed to choose between Material-UI and Muse UI. (Using material design was no question for me at this point.) I considered other libraries as well. But I quickly fell in love with Material-UI's [checkbox animation](http://www.material-ui.com/#/components/checkbox). It was really robust anyway.

![checkbox animation](https://thepracticaldev.s3.amazonaws.com/i/mj567oylnus5hx27ghvg.gif)

First, I wanted to go with Muse UI, which is a port of Material-UI because I thought I would like Vue.js more than React.js.

However, its documentation was Chinese only at that time, so I choose the original library instead.

Having the CSS and HTML kind of combined into JavaScript using React.js felt a bit strange for the first time. Later, when I used Vue.js for some small client projects, I realized that I actually like the React way a bit more, especially with Styled Components.

Eventually, I created this example project. So I was able to start with my real one called [Facebook Searcher](https://facebooksearcher.com/):

[
	![Facebook Searcher](https://thepracticaldev.s3.amazonaws.com/i/clkoqfkhguxaombf2p9a.png)
](https://facebooksearcher.com/)

It is a simple search form that builds a link so you can make custom searches currently for people on Facebook the regular way.
You can already use the implemented fields and it already gives more freedom than its competitor.

For example, you can list Facebook users with an interest in both sexes (which Facebook supports). It is still under development and some features are waiting for implementation.
So feel free to let me know if you want to support this project in any way!

#### [Other reasons](https://github.com/michaelrambeau/bestofjs/issues/91#issuecomment-307631163)

### What is [Razzle](https://github.com/jaredpalmer/razzle)?

A framework-agnostic build tool for server-rendered universal JavaScript applications.

#### Why Razzle?
Server side rendering is easy with Razzle. This was a must have for me. Plus, it doesn't force you to use solutions that you don't want to use.

> So it "...is [...] minimalistic..." ([source](https://github.com/jaredpalmer/razzle/issues/289#issuecomment-306586593))

Hot module reloading is also a nice feature to have. Customizing or extending defaults is simple too.

> All this makes Razzle "...a nearly framework-agnostic build system..." which "...will 100% work with Angular, Vue, Rax, Preact, Inferno, React-XP, RN-Web..." - Jared Palmer ([source](https://github.com/jaredpalmer/razzle/issues/289#issuecomment-306593963))

#### [Who is using it?](https://github.com/jaredpalmer/razzle/issues/332)

### What's next?
[Facebook Searcher](https://facebooksearcher.com) was first "deployed" to an old-school hosting provider. I had Secure Shell access there, so I was able to install Node.js.

I used Process Manager 2 to make sure it is running no matter what. Of course, this wasn't as fast as having a static website. Plus, I didn't have a good framework for deployments and updates in place. After a while, I started to save the HTML by hand and publish the application on Netlify this way. It was more reliable and the application loaded way faster too.

Later on, I switched to Firebase Hosting, which is even faster and even more reliable in general. I implemented the static site generation feature somewhere at this point. Doing it by hand was unsustainable for sure. Now I can build and deploy Facebook Searcher with just one command. I can now focus hard on implementing the remaining features.

![firebase deploy.png](https://thepracticaldev.s3.amazonaws.com/i/g4pfcbb29q2h8rgf0a0j.png)

Deploying our application to Firebase Hosting is easy. Moreover, we can still deploy it as a Firebase Function instead ([basic example](https://github.com/jaredpalmer/razzle/tree/master/examples/with-firebase-functions)). Maybe this topic alone would worth another article regardless the easiness.

Currently, my project doesn't come with rooting. If you need it for your project, you can add a router or you can consider using [After.js](https://github.com/jaredpalmer/after.js) instead, which is basically Razzle with routing and related capabilities.

I am also looking forward to updating the project to the 1. version of Material-UI once they release it and add back the checkbox animations that I love so much.

## Take away

Experimenting and or reading this article you can use Material-UI quickly and easily in a sophisticated way. So go ahead and build something wonderful! 🎉

Would you use this setup? Do you prefer something else?

⬇ **Reply**, **ask** and **share your experience** in the comments below!

Did you enjoy this article?

⬇ 💖**Heart** the article!

**Share** this step-by-step guide **with** your **friends** and colleges!

Copy the link from the address bar. Message your peers directly. 👋Say hi and send the article to them.

### 💌 Newsletter
by Erik Engi

> **[Subscribe now](https://my.sendinblue.com/users/subscribe/js_id/32wxl/id/2)** and get actionable technical articles into your inbox.

Erik will only email you when he has something important to say. Just like you, he is usually very busy. So this will only happen every now and then and you can unsubscribe at any time.

Follow [Erik Engi on DEV](https://dev.to/kireerik) and [on Medium](https://medium.com/@erikengi) to get notified about new articles.

### Work with Erik Engi
Do you or your company have valuable projects and products? Want to extend your team with a world-class developer?

[Hire now](https://docs.google.com/forms/d/e/1FAIpQLSdRPRPFiYihG03lNUaKa1hU6z_BePrDwVCyV65S3ZLhvADyIw/viewform) – Erik is available for hire

###<center>[Oengi.com](https://oengi.com/)</center>

Erik can work full time for you or at your company.
Do you or your team need programming help? [Book 1:1 session](https://docs.google.com/forms/d/e/1FAIpQLSdRPRPFiYihG03lNUaKa1hU6z_BePrDwVCyV65S3ZLhvADyIw/viewform?entry.600696459=mentorship)s with Erik!


---

*Originally published at [codementor.io](https://www.codementor.io/kireerik/material-ui-get-started-fast-react-16-fjan7erke).*