Fast as C, slick as Ruby

Install Learn Try Online


Crystal’s syntax is heavily inspired on Ruby’s, so it feels natural to read and easy to write, and has the added benefit of a lower learning curve for experienced Ruby devs.

# A very basic HTTP server
require "http/server"

server = do |context|
  context.response.content_type = "text/plain"
  context.response.print "Hello world, got #{context.request.path}!"

puts "Listening on"

Read more


Crystal is a compiled language, allowing it to run blazingly fast with a very low memory footprint. It relies on LLVM for emitting native code, thus making use of all the optimisations built into the toolchain.

Web server throughput

Source: costajobs/app-servers
Read more

Type system

Crystal is statically type checked, so any type errors will be caught early by the compiler rather than fail on runtime. Moreover, and to keep the language clean, Crystal has built-in type inference, so most type annotations are unneeded.

def shout(x)
  # Notice that both Int32 and String respond_to `to_s`

foo = ENV["FOO"]? || 10

typeof(foo) # => (Int32 | String)
typeof(shout(foo)) # => String

Read more

Null reference checks

All types are non-nilable in Crystal, and nilable variables are represented as an union between the type and nil. As a consequence, the compiler will automatically check for null references in compile time, helping prevent the dreadful billion-dollar mistake.

if rand(2) > 0
  my_string = "hello world"

puts my_string.upcase

Running the previous file:

$ crystal
Error in undefined method 'upcase' for Nil (compile-time type is (String | Nil))

puts my_string.upcase


Crystal’s answer to metaprogramming is a powerful macro system, which ranges from basic templating and AST inspection, to types inspection and running arbitrary external programs.

class Object
  def has_instance_var?(name) : Bool
    {{ &.name.stringify }}.includes? name

person = "John", 30
person.has_instance_var?("name") #=> true
person.has_instance_var?("birthday") #=> false

Read more

Concurrency Model

Crystal uses green threads, called fibers, to achieve concurrency. Fibers communicate with each other using channels, as in Go or Clojure, without having to turn to shared memory or locks.

channel = Channel(Int32).new
total_lines = 0
files = Dir.glob("*.txt")

files.each do |f|
  spawn do
    lines =
    channel.send lines

files.size.times do
  total_lines += channel.receive

puts total_lines

Read more


Crystal has a dedicated syntax to easily call native libraries, eliminating the need to reimplement low-level tasks.

# Fragment of the BigInt implementation that uses GMP
lib LibGMP
  alias Int = LibC::Int
  alias ULong = LibC::ULong

  struct MPZ
    _mp_alloc : Int32
    _mp_size : Int32
    _mp_d : ULong*

  fun init_set_str = __gmpz_init_set_str(rop : MPZ*, str : UInt8*, base : Int) : Int
  fun cmp = __gmpz_cmp(op1 : MPZ*, op2 : MPZ*) : Int

struct BigInt < Int
  def initialize(str : String, base = 10)
    err = LibGMP.init_set_str(out @mpz, str, base)
    raise"invalid BigInt: #{str}") if err == -1

  def <=>(other : BigInt)
    LibGMP.cmp(mpz, other)

Read more


Crystal libraries are packed as Shards, and distributed via git without needing a centralised repository. Built in commands allow dependencies to be easily specified through a YAML file and fetched from their respective repositories.

name: my-project
version: 0.1
license: MIT

crystal: 0.21.0

    github: crystal-lang/crystal-mysql
    version: ~> 0.3.1

Crystal top sponsors

Meet all

Articles from our blog

authors/mdavid.jpg María Inti David 5 days ago

Announcing Crystal CodeCamp SF2017


authors/spalladino.jpg Santiago Palladino 24 Feb 2017

State of Crystal at 0.21

What did we do since new year?


authors/lschutz.jpg Leonard Schütz 06 Jan 2017

The Charly programming language

Guest blog post by Leonard Schütz


More articles

Community channels

Show all