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 for 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.

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, things like:

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 side-by-side:

Routes

Rails

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

Phoenix

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

Migration

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>
  

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.

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. 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.

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 fast, hun?

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 about to publish: Phoenix for Rails Developers.

The book is for developers that invested thousands of hours learning Rails and and want to benefit from that knowledge to learn Phoenix.

You might also like

Writting a book

I am writting a book to help experienced Rails developers to learn Phoenix, using the knowledge they acquired over the years.

Free book

Today I released "Versioned APIs with Phoenix" free book. It covers three different strategies on API versioning with Phoenix...

Phoenix API versioning: Accept Header

This is the second part of the API versioning series. This post shows how to achieve API versioning using the Accept header...

Learning a new framework from scratch is hard

You invested thousands of hours learning Rails and how to master its features to build web applications. This book will help you to learn Phoenix, using the knowledge you already have.

Get the book