5 reasons you should use Phoenix instead of Rails in your next project

Whenever I started a new project in the past, Rails was my standard tool to go with. Having been using it for almost a decade, it was the perfect tool to get something done, in the most efficient and productive way.

I have to confess that many times I tried to use something different. I played with Erlang, go and node.js, but none of them gave me the “developer happiness” experience I was used to get from Rails.

Sticking to Rails meant I was compromising performance, since most of the technologies I mentioned above performed better than Rails; that wasn’t a problem at all, the “developer happiness” was more important than performance for me.

Two years ago I stumbled upon Phoenix, a web framework written in Elixir. I was able to develop a web application in a similar way I was used to develop using Rails, but with a “tiny” difference: Phoenix was fast, way faster than Rails.

After having used it in a few projects, where some of them were complete migrations of Rails projects to Phoenix, it quickly became my default tool to build web applications, putting Rails in the second position.

This post is about the 5 reasons that made me switch and why you should consider using Phoenix instead of Rails in your next project.

1. Common concepts

When working in Rails projects, you are used to rely on the framework to a number of things that you don’t even think about anymore, for example:

  • The directory structure
  • The naming conventions
  • The database migrations
  • The use of dependencies
  • The ActiveRecord features
  • The ERb templates
  • The form helpers
  • The built-in support for testing

Those things are directly connected to the “developer happiness” effect that Rails has in developers. Why should you consider using another framework that doesn’t offer the things that you are used?

Well, the good news is that Phoenix not only provides the features to all those topics, but it also makes it simple to Rails developers to understand. Let’s compare some of the features:

Routes

Rails

get '/books', to: 'books#index'
get '/books/:id', to: 'books#show'

Phoenix

get "/books", BookController, :index
get "/books/:id", BookController, :show

Migrations

Rails

class CreateBooks < ActiveRecord::Migration[5.0]
def change
create_table :books do |t|
t.string :title
t.text :description
t.decimal :price
t.string :image_url
      t.timestamps
end
end
end

Phoenix

defmodule Storex.Repo.Migrations.CreateStoreBooks do
use Ecto.Migration
  def change do
create table(:store_books) do
add :title, :string
add :description, :text
add :price, :decimal
add :image_url, :string
      timestamps()
end
end
end

Templates

Rails

<section class="book-list">
<ul class="grid">
<% @books.each do |book| do %>
<li class="grid-item">
<div class="book book-small">
<h2 class="book__title"><%= book.title %></h2>
<span class="book__price"><%= book.price %></span>
</div>
</li>
<% end %>
</ul>
</section>

Phoenix

<section class="book-list">
<ul class="grid">
<%= for book <- @books do %>
<li class="grid-item">
<div class="book book-small">
<h2 class="book__title"><%= book.title %></h2>
<span class="book__price"><%= book.price %></span>
</div>
</li>
<% end %>
</ul>
</section>

2. Simplicity

Phoenix goes a long way to make things simpler. You won’t find the same number of “magics per line of code” present in Rails, and you should see that as a positive thing. The framework authors strive to find the perfect balance between abstraction and explicitness. It leads to a simpler way to use and understand the framework features. Take that example from the router:

...
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
end
...

Although Phoenix generated that code by default, a developer can still understand what happens when a request is performed and where to perform changes to influence the way a request is handled.

The fine balance between clarity and abstraction is present in every component of Phoenix and you will find yourself browsing the framework code to learn more about its features, as also a point of inspiration.

3. Productivity

Rails is well known for its productivity. It enables small teams and companies to launch complex projects, which before would require a lot of man power. Rails became the perfect tool for building prototypes. There is no doubt about “productivity” being one of the reasons that made Rails so popular.

Phoenix go further on providing developers two types of productivity:

Short term

That’s the same productivity you find in Rails. It’s based on the features that enable developers to get the project started and the initial development of functionalities. You will find a well-crafted documentation, generators to quickly get basic features done and conventions over configurations.

Long term

The official description of Phoenix is “A productive web framework that does not compromise speed and maintainability”. That bold statement shows how Phoenix position itself when comparing it to similar web frameworks. Both “maintainability” and “speed” are some of the reasons behind the long-term productivity you’ll find in Phoenix. Maintainability means that you’ll still enjoy working in a Phoenix project after a couple of months. Speed means that you won’t have to worry about optimizing every corner of your Phoenix application, plastering caching calls everywhere in order to extract a few milliseconds.

4. Fast, really fast!

Phoenix is damm fast. If you are used to see response times in ms, take a look at this:

[info] GET /
[debug] Processing with StorexWeb.PageController.index/2
Parameters: %{}
Pipelines: [:browser]
[info] Sent 200 in 191µs

Yes, that’s correct, you are seeing µs response times.

You can also see the journey that enabled Phoenix to run 2 million clients in a single server:

Pretty neat, hun?

5. Scalable

Phoenix is written in Elixir, which runs on top of the Erlang VM, a battle-tested piece of software used by telecoms, banking, e-commerce and instant messaging to power their massively scalable and high availability system.

Phoenix applications are able to adapt themselves to changes in load and available resources. Even under heavy load, a Phoenix application is able to accept and handle more incoming requests, even if that means increasing the response times in order to keep accepting traffic. The same applies to running your Phoenix application in different types of machines (e.g. one with a single core and other with 40 cores), where the Erlang VM makes sure to map the concurrency of your application to the machine parallelism, so that you don’t have to tweak it manually.

Those things are only possible because Phoenix runs on top of the Erlang VM.


How to start using Phoenix?

If you are a Rails developer and want to start using Phoenix, you should check the book I am publishing next month: Phoenix for Rails Developers.

It was written for developers that invested thousands of hours learning Rails and and want to benefit from that knowledge to learn Phoenix.