Tutorial: Learn Crystal from Scratch (2026)
Crystal combines Ruby-like syntax with compiled performance via LLVM. I have used it for web APIs, CLI tools, and high-throughput data pipelines. The syntax is so close to Ruby that many Ruby scripts need only minor adjustments to compile with Crystal.
Crystal's concurrency model — fibers with channels, inspired by Go and Erlang — makes it easy to write efficient concurrent programs. The type inference is global, so you rarely need type annotations.
Type Inference
Crystal's type inference is global and powerful. The compiler analyzes your entire program to determine types without annotations. Union types are inferred automatically when a variable can hold multiple types. The compiler reports type errors with detailed messages about where incompatible types originate.
def process(x)
if x.is_a?(Int32)
x + 1
elsif x.is_a?(String)
x.upcase
else
"unknown"
end
end
puts process(42) # Int32
puts process("hi") # String
puts process(true) # String
# Inferred return type: (Int32 | String)
Fibers and Channels
Fibers are lightweight coroutines managed by Crystal's runtime. Channels provide CSP-style communication: send puts a value, receive gets it. Multiple fibers can operate on the same channel. The runtime schedules fibers on a thread pool. Use spawn to create a fiber and Channel(T) for typed channels.
channel = Channel(Int32).new
spawn do
10.times do |i|
channel.send(i * 10)
end
channel.close
end
spawn do
while val = channel.receive?
puts "Got: #{val}"
end
end
sleep 0.1
Macros
Crystal macros run at compile time, operating on AST nodes. They enable metaprogramming similar to Nim but with Ruby-like syntax. macro definitions create compile-time code generators. {{ }} interpolates into the generated code. Macros can inspect types, iterate over fields, and generate methods and types.
macro define_getters
{% for type in @type.instance_vars %}
def {{type.name}}
@{{type.name}}
end
{% end %}
end
class Person
@name : String
@age : Int32
define_getters
def initialize(@name, @age)
end
end
p = Person.new("Alice", 30)
puts p.name
puts p.age
Shards
Shards is Crystal's package manager. Dependencies go in shard.yml. shards install resolves and installs them. Shards supports git and path sources. Crystal's standard library is extensive — HTTP servers, JSON/XML parsers, crypto, and more are built in, reducing the need for third-party packages.
# shard.yml
name: myapp
version: 0.1.0
dependencies:
kemal:
github: kemalcr/kemal
version: ~> 1.0
pg:
github: will/crystal-pg
version: ~> 0.25
# Install: shards install
HTTP and Web
Crystal's standard library includes HTTP::Server for building web applications without frameworks. The server uses fibers per request, enabling high concurrency. The Kemal framework provides Sinatra-like syntax. Crystal's HTTP client supports streaming, SSL, and connection pooling.
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello, World!"
end
address = server.bind_tcp 8080
puts "Listening on #{address}"
server.listen
# With Kemal framework:
# require "kemal"
# get "/" do
# "Hello, World!"
# end
# Kemal.run
C Bindings
Crystal calls C libraries via @[Link] and fun declarations. The @[Link] attribute tells the linker which library to use. Crystal handles pointer types, callbacks, and struct mapping. There are bindings for libcurl, sqlite3, openssl, and many popular C libraries.
@[Link("sqlite3")]
lib SQLite3
fun open(path : UInt8*, db : Void**) : Int32
fun close(db : Void*) : Int32
fun exec(
db : Void*,
sql : UInt8*,
callback : (Void*, Int32, Void**, Void**) -> Int32,
arg : Void*,
errmsg : Void**
) : Int32
end
db = Pointer(Void).malloc(1)
SQLite3.open("test.db", pointerof(db))
puts "DB opened"
Frequently Asked Questions
Crystal vs Ruby?
Crystal compiles to native code, is statically typed, and performs 10-100x faster for CPU-bound work. Syntax is almost identical to Ruby.
Does Crystal have a garbage collector?
Yes, Crystal uses an incremental, generational GC based on Boehm-Demers-Weiser. There are no manual memory management calls.
What are Crystal shards?
Shards are Crystal packages, similar to Ruby gems or npm packages. They are distributed via Git repositories.
Can I use Crystal on Windows?
Crystal has experimental Windows support via MinGW. Linux and macOS are the primary targets.
Originally published on Ayodhyyya. Last updated June 1, 2026.