Up and Running with Elixir, Phoenix, and React

April 5th, 2019

What's this Elixir business?

My latest project is a web app using Elixir and React. It’s my first time programming in a functional language. So far, it’s been rather difficult to switch gears from Object Oriented to Functional. I’ve been trying to stay in this new mindset, but my OO habits have persisted. I’ll discuss lessons I’ve learned about Functional Programming in a different post. I had to quickly ramp up and learn Elixir for this new project. Consequently, I wanted to deploy a “Hello World” to Heroku and build around that since my final project would need to be deployed anyway. I have always found it easier to incrementally change a deployed app rather than deploy a complete app. As such, this particular post will be about setting up a bare bones Elixir and React app, using Phoenix (a frontend framework for Elixir), and deploying it to Heroku.

Setup and deployment was not as complicated as I’d originally anticipated. Maggie, an 8th Light Crafter, sent me an awesome guide on Github that I'll link below. Elixir also provides great guides for getting started and deploying to Heroku. Check out the docs.

Functional Programming

As I mentioned earlier, I’ll review what I’ve come to understand about FP in another post. However, I do want to provide a quick note about FP and some resources I’ve been using to learn FP. From what I understand so far, FP uses a declarative approach to build software. The focus is on functions as first class citizens and higher order functions where functions can be assigned to variables and be passed around as return values; functions can accept other functions as arguments, and functions can return other functions. The other focus is immutability, where you avoid mutating state by creating new state instead of modifying state that already exists. These and other tactics are used to declare what we want our end result to be rather than imperatively stating how everything should be done. Here are some resources I’ve found to be helpful so far:

Master the JavaScript Interview What is Functional Progamming by Eric Elliott

Let’s Get Functional with Elixir by Nate Taylor

A Beginner Friendly Intro to Functional Programming by Johann Schuster

Lambda Cast Podcast

Let's get started

More on FP later when I have the energy. I think it’ll be another several months before I have a grasp on functional programming. For now, let’s get back to our regularly scheduled program. After installing Elixir, starting a new project by invoking an Elixir and Phoenix tool in the command line, adding React, and deploying to Heroku, I ended up with a simple page that had a header and title. I’m going to review the steps that I took to end up with a deployed “Hello World”. I also want to mention that I did not include a database. This is a bare bones app without any data, models, schema, or anything related to persisting data.

Here are the resources that I used along the way:

Intro to Mix

CLISample by Maggie Shemayev

A Phoenix + React Initial Setup that Actually Works by Rest Respati

Hello World with Phoenix by Angelika Tyborska

Installation

Disclaimer: I will not be including any Windows installation instructions. Sorry.

For this project, you will need to install Elixir and Phoenix. Phoenix is written in Elixir. It’s a web development framework that is usually compared to Ruby on Rails since it implements the Model View Controller (MVC) pattern. Since this is a React application, you’ll also need to have Node.js and NPM on your machine first. Node.js helps with executing JavaScript code. And NPM (Node Package Manager) helps us install libraries, usually called dependencies, to our application. NPM is distributed by Node.js, so when you install Node.js, you also get NPM. Let’s start by installing Node.js.

Node.js and NPM

It looks like there are a couple of ways of installing Node.js and NPM. Since I have a Mac, way back in the day when I first started coding (couple of years ago), I used Homebrew to install Node.js. You can go here to install and learn more about Homebrew. They give you a command to run in your terminal -- do that. After that, in your terminal run the following command: $ brew install node

Then you will be set with Node and NPM. You can check the versions of each typing the following in the terminal: $ node -v $ npm -v

The other way is to go to https://nodejs.org/en/download/ and follow the remaining download instructions.

Elixir

Now that you’re set with Node and NPM, let’s install Elixir. We’ll take care of React later. If you’re on a Mac and have Homebrew, run the following in your command line: $ brew update $ brew install elixir

Elixir has installation guides if you went another route, have a different machine, or had trouble installing: https://elixir-lang.org/install.html

Run the following in your terminal to make sure you successfully downloaded Elixir: $ elixir -v

Phoenix

To get started with Phoenix, you’ll first need the Hex package manager. To install Hex, run the following: $ mix local.hex

To install the Phoenix Mix archive, run the following command: $ mix archive.install hex phx_new 1.4.3

Had trouble with Phoenix? Check out the installation guide.

Setup

Now that we have Elixir, Hex, Phoenix, and Node.js we’re ready to setup our app. Starting from the directory for where you want your project to live, run the following: $ mix phx.new phoenixreactapp --no-brunch --no-ecto

You should see something like the following: Create Phoenix Deps

You’ll be asked if you want to fetch and install dependencies. Answer “no” to that. We’ll install those later. You should see something similar to the following in your terminal:

Create Phoenix Terminal

Let’s run the following: $ mix deps.get $ npm install

React

Cool, let’s get started with adding React to our stack. We're going to add some dependencies and new files. I want to apologize in advance - I've included pics of code instead of copy/pastable content. I'm working through formatting issues. Sorry. (Disclaimer: I'm using webpack in this tutorial. I noramlly use create-react-app, but I didn't know how that would play out with Phoenix. Usually I also set up a proxy in MERN stack apps. But I didn't need to do that for this app. That probably has something to do with webpack. More findings on that later.) Let's first add the React preset to our .babelrc file. The file should contain:

React Preset
Next, we’re going to be adding some dependencies to our package.json file.

Run the following in the terminal: $ cd assets $ npm i —save react react-dom react-router-dom @babel/preset-react

Let’s start modifying and adding some files. In js/app.js, replace the contents with the following:

app.js

Make a new file called Root.js within the js folder. Add the following content:

Root.js

Within the js folder, add two new folders: components and pages. Within js/components add a file Header.js with the following contents:

Header.js

Within js/components add a file Main.js with the following:

Main.js

Within js/pages add a index.js file with the following:

index.js

Alright, that should be all that’s needed for React for now. Let’s head over to Phoenix to make sure that our React code will be rendered. Replace the contents in templates/layout/app.html.eex with the following:

app.html.eex

Replace the contents in templates/page/index.html.eex with the following: <div id="react-app"></div>

Let’s make sure everything is installed just in case. From the assets directory, run npm install in your terminal.

Now let’s move out of assets to the root directory. Run the following: $ mix phx.server

Navigate to localhost:4000 in your browser. You should see your page with a header and title!

Heroku

Deploying to Heroku was pretty straightforward. There is a great guide in Phoenix that I followed step by step: https://hexdocs.pm/phoenix/heroku.html
I don’t see the need in rewriting the guide. It’s pretty thorough and I didn’t deviate from the directions. The only customization I made was omitting anything that dealt with a database. I ignored all database instructions for all resources.

There was one important gotcha that made my deployment crash. When you have set up everything and you're about to deploy, in the config/prod.exs file, the following line needs to be commented out:

importconfig “prod.secret.exs"

It'll probably be the last line of the file. If it's not commented out, the app will not deploy.

And with that, you should be fully deployed. Congrats! Feel free to [reach out](https://twitter.com/tiffani
elmore "Tiffani twitter") to me if you get stuck! I'm looking forward to trying this out with create-react-app and adding a database. More on that to come!