Beginner’s Guide: Creating Your First Crystal Project

Beginner’s Guide: Creating Your First Crystal Project

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.

1) Install Crystal

brew install crystal
  • Linux

    • Check the official installation page for distro-specific instructions:
      https://crystal-lang.org/install/
  • Verify

crystal --version
shards --version

Optional tools you’ll probably want soon:

  • VS Code extension (Crystal + LSP): https://marketplace.visualstudio.com/items?itemName=crystal-lang-tools.crystal-lang
  • Linter (Ameba): https://marketplace.visualstudio.com/items?itemName=veelenga.crystal-ameba

2) Create a new project

Crystal uses shards (like Ruby’s Bundler) for dependency management and project scaffolding.

  • App template (recommended for CLI apps and services):
mkdir hello_crystal && cd hello_crystal
shards init app hello_crystal
  • Library template (if you’re building a shard/gem-like package):
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

3) Write your first program

Open src/hello_crystal.cr and print a greeting:

# src/hello_crystal.cr
puts "Hello, Crystal!"

Run it:

crystal run src/hello_crystal.cr

4) Manage dependencies (when you need them)

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.

5) Format your code

Crystal ships a formatter:

crystal tool format

Run it from the project root to format all sources.

6) Add a simple test (spec)

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

7) Build a binary

Two common ways to build:

crystal build --no-debug --release src/hello_crystal.cr -o bin/hello_crystal
  • Using shards (works when 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

9) Optional: Lint with Ameba

Ameba is Crystal’s code style linter (similar to RuboCop).

brew tap crystal-ameba/ameba
brew install ameba
ameba
ameba --fix

Visual overview

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]

What’s next?

  • Explore popular shards:
    • Web frameworks: Kemal (Sinatra-like), Lucky and Amber (Rails-like)
    • Linting: Ameba
    • HTTP client: Crest
  • Build a CLI tool, a web service, or a small library and publish it as a shard.

You’ve just created, tested, and built your first Crystal project. Keep it small, iterate quickly, and enjoy the speed and expressiveness of Crystal.


Source link

About Cybernoz

Security researcher and threat analyst with expertise in malware analysis and incident response.