A step-by-step tutorial to install Crystal and create, run, test, and build your first project using shards.
Getting started with Crystal is quick if you follow a few simple steps. In this guide, you’ll install Crystal, scaffold a new project, write a tiny program, run tests, and produce a release build.
I’ll keep it minimal and practical so you can get productive fast.
brew install crystal
Linux
Verify
crystal --version
shards --version
Optional tools you’ll probably want soon:
Crystal uses shards
(like Ruby’s Bundler) for dependency management and project scaffolding.
mkdir hello_crystal && cd hello_crystal
shards init app hello_crystal
mkdir my_lib && cd my_lib
shards init lib my_lib
This creates a basic structure (for an app):
hello_crystal/
├─ shard.yml
└─ src/
└─ hello_crystal.cr
Open src/hello_crystal.cr
and print a greeting:
# src/hello_crystal.cr
puts "Hello, Crystal!"
Run it:
crystal run src/hello_crystal.cr
If you add dependencies to shard.yml
, install them with:
shards install
You generally won’t need this for the very first “hello world,” but it’s essential once you pull in libraries like HTTP clients or web frameworks.
Crystal ships a formatter:
crystal tool format
Run it from the project root to format all sources.
Create a spec file:
# spec/hello_crystal_spec.cr
require "spec"
require "../src/hello_crystal"
describe "hello_crystal" do
it "runs without raising" do
expect { Crystal.main }.not_to raise_error
end
end
If your app doesn’t define Crystal.main
, you can test a function you write instead. For a beginner-friendly pattern, wrap your app code in a module:
# src/hello_crystal.cr
module HelloCrystal
def self.greet(name : String = "Crystal")
"Hello, #{name}!"
end
end
puts HelloCrystal.greet
And test it:
# spec/hello_crystal_spec.cr
require "spec"
require "../src/hello_crystal"
describe HelloCrystal do
it "greets with default name" do
HelloCrystal.greet.should eq "Hello, Crystal!"
end
it "greets a custom name" do
HelloCrystal.greet("World").should eq "Hello, World!"
end
end
Run tests:
crystal spec
# or verbose:
crystal spec -v
Two common ways to build:
crystal build --no-debug --release src/hello_crystal.cr -o bin/hello_crystal
shard.yml
defines targets):shards build --no-debug --release
Run your binary:
./bin/hello_crystal
For production-like builds (strict dependencies and no dev deps):
shards build --release --no-debug --production
crystal tool dependencies ./src/hello_crystal.cr
Ameba is Crystal’s code style linter (similar to RuboCop).
brew tap crystal-ameba/ameba
brew install ameba
ameba
ameba --fix
Here’s a simple flow of your first project:
flowchart LR A[Install Crystal] --> B[shards init app hello_crystal] B --> C[Edit src/hello_crystal.cr] C --> D[crystal run] D --> E[crystal spec] E --> F[crystal tool format] F --> G[shards build --release] G --> H[Run ./bin/hello_crystal]
You’ve just created, tested, and built your first Crystal project. Keep it small, iterate quickly, and enjoy the speed and expressiveness of Crystal.