입문자를 위한 Crystal 프로젝트 만들기

Crystal는 Ruby와 비슷한 문법에 정적 컴파일 성능을 더한 매력적인 언어예요. 이 글에서는 제가 실무에서 사용하는 최소한의 흐름으로, 설치 → 프로젝트 생성 → 실행 → 테스트 → 빌드까지 빠르게 통과해봅니다. 처음 시작하는 분들이 “바로 써본다”에 집중할 수 있도록 가볍게 구성했습니다.

1) Crystal 설치

  • macOS (Homebrew)
brew install crystal
  • Linux

    • 배포판마다 설치 방법이 달라요. 공식 문서에서 본인 환경을 확인하세요: https://crystal-lang.org/install/
  • 설치 확인

crystal --version
shards --version
  • 개발에 바로 도움이 되는 도구
    • VS Code 확장(LSP 포함): https://marketplace.visualstudio.com/items?itemName=crystal-lang-tools.crystal-lang
    • Linter(Ameba): https://marketplace.visualstudio.com/items?itemName=veelenga.crystal-ameba

2) 새 프로젝트 만들기

Crystal은 shards라는 의존성/프로젝트 관리 도구를 씁니다. 앱을 만든다면 app 템플릿이 편해요.

  • 애플리케이션(일반 CLI/서비스)
mkdir hello_crystal && cd hello_crystal
shards init app hello_crystal
  • 라이브러리(배포용 shard)
mkdir my_lib && cd my_lib
shards init lib my_lib

생성된 기본 구조(앱 기준):

hello_crystal/
├─ shard.yml
└─ src/
   └─ hello_crystal.cr

3) 첫 코드 작성

src/hello_crystal.cr 파일을 열어 간단한 출력부터 시작해봅니다.

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

실행:

crystal run src/hello_crystal.cr

조금만 구조를 잡고 싶다면 모듈로 감싸 재사용/테스트를 쉽게 만듭니다.

# src/hello_crystal.cr
module HelloCrystal
  def self.greet(name : String = "Crystal")
    "Hello, #{name}!"
  end
end

puts HelloCrystal.greet

4) 의존성 관리(필요해질 때)

shard.yml에 라이브러리를 추가했다면 아래로 설치합니다.

shards install

처음 “hello world” 수준에선 필요 없지만, HTTP 클라이언트나 웹 프레임워크를 넣을 때 필수입니다.

5) 코드 포맷

Crystal은 기본 포매터를 제공합니다. 프로젝트 루트에서 실행하면 전체 소스를 정리합니다.

crystal tool format

6) 간단한 테스트(spec)

제가 선호하는 방식은 간단한 함수에 대해 동작을 고정하는 것입니다.

테스트 파일 생성:

# spec/hello_crystal_spec.cr
require "spec"
require "../src/hello_crystal"

describe HelloCrystal do
  it "기본 인사말을 출력한다" do
    HelloCrystal.greet.should eq "Hello, Crystal!"
  end

  it "사용자 이름으로 인사한다" do
    HelloCrystal.greet("World").should eq "Hello, World!"
  end
end

테스트 실행:

crystal spec
# 자세히 보고 싶다면
crystal spec -v

7) 바이너리 빌드

처음엔 crystal build를 직접 쓰는 게 이해가 빠릅니다.

  • Crystal 직접 빌드:
crystal build --no-debug --release src/hello_crystal.cr -o bin/hello_crystal
  • shards로 빌드(shard.yml에 target이 있을 때):
shards build --no-debug --release

실행:

./bin/hello_crystal

좀 더 엄격한 프로덕션 느낌의 빌드:

shards build --release --no-debug --production
# --production = --frozen + --without-development

8) 의존성 그래프 보기(디버깅에 유용)

crystal tool dependencies ./src/hello_crystal.cr

9) 선택: Lint(Ameba)

Rubocop과 유사한 스타일/버그 검출기입니다.

  • 설치(macOS 예시)
brew tap crystal-ameba/ameba
brew install ameba
  • 실행/자동수정
ameba
ameba --fix

전체 흐름 한눈에 보기

 flowchart LR
  A[Crystal 설치] --> B[shards init app hello_crystal]
  B --> C[src/hello_crystal.cr 작성]
  C --> D[crystal run]
  D --> E[crystal spec]
  E --> F[crystal tool format]
  F --> G[shards build --release]
  G --> H[./bin/hello_crystal 실행]

다음 단계

  • 자주 쓰는 shard들
    • 웹: Kemal(간단, Sinatra 느낌), Lucky/Amber(Rails 느낌)
    • Lint: Ameba
    • HTTP 클라이언트: Crest
  • 작은 CLI 도구나 웹 서비스를 만들어 보며 감각을 익히세요. 필요해질 때 테스트를 보강하고, shards로 의존성을 관리하면 됩니다.

참고: 설치 시 발생할 수 있는 OpenSSL 관련 오류 해결은 별도 문서(“How to fix install error in Crystal”)에서 자세히 다룹니다. 우선은 위 흐름으로 첫 프로젝트를 끝까지 만들어 보고, 막히는 지점이 생기면 개별 트러블슈팅 글을 참고하세요.