
News
Become a Crystal sponsor in only 3 simple steps via OpenCollective
ContributeYou can tap into the expertise of the very creators of the language to guide you in your implementation.
Hire UsTop Sponsors
Success stories



Crystal’s standard library comes with a whole range of libraries that let you start working on your project right away.
# A very basic HTTP server
require "http/server"
server = HTTP::Server.new do |context|
context.response.content_type = "text/plain"
context.response.print "Hello world, got #{context.request.path}!"
end
address = server.bind_tcp(8080)
puts "Listening on http://#{address}"
# This call blocks until the process is terminated
server.listen
Crystal is statically typed and type errors are caught early by the compiler, eliminating a range of type-related errors at runtime.
Yet type annotations are rarely necessary, thanks to powerful type inference. This keeps the code clean and feels like a dynamic language.
def shout(x)
# Notice that both Int32 and String respond_to `to_s`
x.to_s.upcase
end
# If `ENV["FOO"]` is defined, use that, else `10`
foo = ENV["FOO"]? || 10
puts typeof(foo) # => (Int32 | String)
puts typeof(shout(foo)) # => String
nil
values are represented by a special type, Nil
, and any value that can be
nil
has a union type including Nil
.
As a consequence, the compiler can tell whether a value is nilable at compile
time. It enforces explicit handling of nil
values, helping prevent the dreadful billion-dollar mistake.
foo = [nil, "hello world"].sample
# The type of `foo` is a union of `String` and `Nil``
puts typeof(foo) # => String | Nil
# This would be a type error:
# puts foo.upcase # Error: undefined method 'upcase' for Nil
# The condition excludes `Nil` and inside the branch `foo`'s type is `String`.
if foo
puts typeof(foo) # => String
puts foo.upcase
end
Crystal’s syntax is heavily inspired by 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.
class String
def longest_repetition?
max = chars
.chunk(&.itself)
.map(&.last)
.max_by?(&.size)
{max[0], max.size} if max
end
end
puts "aaabb".longest_repetition? # => {'a', 3}
Crystal uses green threads, called fibers, to achieve concurrency. Fibers communicate with each other via channels without having to turn to shared memory or locks (CSP).
channel = Channel(Int32).new
3.times do |i|
spawn do
3.times do |j|
sleep rand(100).milliseconds # add non-determinism for fun
channel.send 10 * (i + 1) + j
end
end
end
9.times do
puts channel.receive
end
Crystal allows to define bindings for C libraries and call into them. You can easily use the vast richness of library ecosystems available.
No need to implement the entire program in Crystal when there are already good libraries for some jobs.
# Define the lib bindings and link info:
@[Link("m")]
lib LibM
fun pow(x : LibC::Double, y : LibC::Double) : LibC::Double
end
# Call a C function like a Crystal method:
puts LibM.pow(2.0, 4.0) # => 16.0
# This example intentionally uses a simple standard C function to be succinct.
# Of course you could do *this specific* calculation in native Crystal as well:
# 2.0 ** 4.0 # => 16.0
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
{{ @type.instance_vars.map &.name.stringify }}.includes? name
end
end
class Person
property name : String
def initialize(@name)
end
end
person = Person.new "John"
p! person.has_instance_var?("name") # => true
p! person.has_instance_var?("birthday") # => false
Crystal libraries are packed with Shards, a distributed dependency manager without a centralised repository.
It reads dependencies defined in shard.yml
and fetches the source code from their repositories.
name: my-first-crystal-app
version: 1.0.0
license: Apache-2.0
authors:
- Crys <crystal@manas.tech>
dependencies:
mysql:
github: crystal-lang/crystal-mysql
version: ~>0.16.0
development_dependencies:
ameba:
github: crystal-ameba/ameba
Become a Crystal sponsor in only 3 simple steps via OpenCollective
ContributeYou can tap into the expertise of the very creators of the language to guide you in your implementation.
Hire Us