Doing Crystal #2: Getting started with Crystal
Tags: crystal, tutorial, series, ruby
Published: 2019-05-22 04:29:21

Hello and welcome to another edition of Doing Crystal. In this article I’m going do a brief overview of the installation of Crystal, Crystal Shards, using the CLI, and setting up a new project.

If you haven’t yet read the first part of this series you can check it out [here](https://dev.to/watzon/doing-crystal-1-a-ruby-comparison-4g9c).

Crystal is pretty easy to install, but sometimes there are hangups. As the language has matured (remember, it is only a 5 year old language) the installation process has gotten simpler and more OS’s are now supported than before. That being said, here are some things to keep in mind:

### Windows Support

This is probably the biggest hangup for a lot of people just getting started with Crystal. As of the writing of this article, Windows is not supported by Crystal. There are [ongoing efforts](https://github.com/crystal-lang/crystal/issues/26) to port the compiler and make compiling on Windows possible, but for now you have 2 options if you want to get started with Crystal on Windows.

1.  Install Linux. You can dual boot, use a VM, or just get rid of Windows all together, but Linux is definitely the best way to develop with Crystal.
2.  Use WSL. This is still using Linux technically, but a little easier. WSL (or the Windows Subsystem for Linux) is a native kernel compatibility layer that allows you to run real Linux inside of Windows. The one hangup here is editor support, which I tried to mitigate with my project [wsl-proxy](https://github.com/watzon/wsl-proxy). Support for WSL has also been added to the [Crystal Language](https://marketplace.visualstudio.com/items?itemName=faustinoaq.crystal-lang) plugin for VS Code.

### Compiling from Source

Compiling from the source files can be quite difficult if you don’t know what you’re doing. There are several [libraries](https://github.com/crystal-lang/crystal/wiki/All-required-libraries) that are required before you can build the compiler. On systems for which there are instructions, namely Ubuntu, Fedora, and OS X, it’s pretty easy to download and install the libraries you need, but for systems such as Arch or Alpine Linux finding the correct libraries can be a little more difficult.

Luckily help is literally a [click](https://gitter.im/crystal-lang/crystal) away.

General installation instructions are located at [crystal-lang.org/reference/installation](https://crystal-lang.org/reference/installation/).

### Shards

Ruby has Bundler, NodeJS has NPM, Rust has Cargo, and Crystal has **Shards**. Shards is a package manager and, like Crystal itself, is still in its infancy. That being said Shards is good at what it does: fetching and installing external Crystal libraries from a git repository.

Shards should come pre-packaged with Crystal. To check if you have it installed, run `shards --help`.

![](https://cdn-images-1.medium.com/max/800/1*PWjZb0sOK8Y6AhjxOfSFtA.png)

If you have shards installed and it is correctly referenced on your PATH you should see this output. The available commands are as follows:

-   **build** — the build command checks your `shard.yml` for binary definitions and builds them if any exist. You can use the `[targets]` option to build specific targets.
-   **check**— checks that your dependencies are up to date.
-   **init** — generates a `shard.yml` file in the current directory.
-   **install** — installs dependencies listed in your `shard.yml`.
-   **list** — lists installed shards.
-   **prune** — removes installed shards that are no longer needed.
-   **update** — updates shards.
-   **version** — gets the version of a project.

Unfortunately, installing binary shards (like you can with `gem install [gemname]` in Ruby) is not yet supported, but hopefully someday it will be.

### The Crystal CLI

The Crystal CLI is an interface to the compiler, the Crystal Playground, tools, documentation generation, test running, and more. First run `crystal --help` to see if you have it installed correctly.

![](https://cdn-images-1.medium.com/max/800/1*P8ofuzW-_kdpPoYzDz1FaQ.png)

If you see this then you’re good to go. Let’s review the CLI’s commands.

-   **init**— Generates a new Crystal project. You can use `crystal init lib [name]` to generate a library project, or `crystal init app [name]` to generate a binary project.
-   **build** — builds a file. In most cases you’ll run `crystal build ./src/project-name.cr`, where `project-name.cr` is the main file that was generated for you when you ran `crystal init`.
-   **docs** — Crystal comes with a built in documentation generator. Personally I feel like there’s a lot missing where documentation generation is concerned, but you can pretty easily generate docs using your comments and type definitions just by running `crystal docs`.
-   **env** — prints the environment information for Crystal. ENV vars include `CRYSTAL_CACHE_DIR`, `CRYSTAL_PATH`, `CRYSTAL_VERSION`, and `CRYSTAL_LIBRARY_PATH.`
-   **eval** — evaluates and runs Crystal code from the standard input.
-   **play** — starts a local Crystal Playground server. This is somewhat like the playground located at [https://play.crystal-lang.org/](https://play.crystal-lang.org/).
-   **run** — builds and runs the supplied filename. Use like `crystal run [file]`.
-   **spec** — builds and runs specs located in the `/spec` directory.
-   **tool** — runs one of the available Crystal tools. Available tools are `context`, `expand`, `format`, `hierarchy`, `implementations`, and `types`.

Now that we’ve gone over the CLI a little, let’s set up a new project.

### Creating a Project

Because it’s been deemed mandatory by the coding gods, let’s create a hello world application.

First let’s open up our terminal of choice and `cd` into a projects directory. In my case I’ll run `cd ~/Projects`. Using the CLI, we’re going to generate a new project scaffold, and then `cd` into our newly created project.

![](https://cdn-images-1.medium.com/max/800/1*c3Wtqrcxnty_rv9m4YvCQw.png)

If you run `ls` you should see the following output:

![](https://cdn-images-1.medium.com/max/800/1*pLg3AkNrZyTwy1A4VXE4sw.png)

The important files here are `shard.yml` and `src/hello_world.cr`. First let’s take a look at `shard.yml`.

![](https://cdn-images-1.medium.com/max/800/1*om3zYH2Dd9gvcdTr-dVlZg.png)

I won’t go over this in detail, as most items should be self explanitory. If you need help with the available options in `shard.yml` you can look at the spec [here](https://github.com/crystal-lang/shards/blob/master/SPEC.md).

Let’s open our main file located at `src/hello_world.cr`.

![](https://cdn-images-1.medium.com/max/800/1*5NRR5sAhP_-D5Kb3OLh7JQ.png)

This is the boilerplate content generated for all new Crystal projects. As you can see our project name of `hello_world` has been PascalCased for the name of the base module. As a convention Crystal uses snake_case for project names, method names, variable names, etc. and PascalCase for constants such as module names and class names.

Now, as convention dictates our hello world application must print something like “Hello, World!” to the console, so let’s make it happen.

For the sake of this example we’ll be a little more verbose than we have to.

![](https://cdn-images-1.medium.com/max/800/1*Rio3_cR7rUAV9LHKUVa9SA.png)

First we create a new class method in the `HelloWorld` module called `say_hello`. You can differentiate class and instance methods by looking for the `self.` syntax. `def self.say_hello` makes a class method, where `def say_hello` makes an instance method.

Our `say_hello` method takes one argument “name” which is assigned a default value of “World”. If we were to run `say_hello` without any arguments the default value of “World” would be used.

Next we go outside of the `HelloWorld` module to run our new method. As `say_hello` is an instance method we can call it with `HelloWorld.say_hello`. Class methods can not be used directly on modules as modules cannot be instantiated.

We finish things off by calling `HelloWorld.say_hello("Manas")` to give a shoutout to the people at [Manas Tech](https://manas.tech) who created Crystal.

Let’s run our program and see the output.

![](https://cdn-images-1.medium.com/max/800/1*PeHgfrR33lK7JugM7Gu8dA.png)

The program will take a few seconds to run as it has to compile first, but you should be greeted with a “Hello, Manas!”. Congratulations! You have written your first Crystal program. Replace `run` with `build` to build a binary to your current directory.

### Conclusion

Crystal is an extremely powerful language and we’ve only scratched the surface so far. Next time we’ll discuss one of the many things that makes Crystal so powerful, it’s type system.

Please don’t forget to hit the Ego Booster button that looks like someone clapping, and if you feel so inclined share this to social media. If you share to twitter be sure to tag me at @_watzon.

Some helpful links:  
[https://crystal-lang.org/](https://crystal-lang.org/)  
[https://github.com/kostya/benchmarks](https://github.com/kostya/benchmarks)  
[https://github.com/kostya/crystal-benchmarks-game](https://github.com/kostya/crystal-benchmarks-game)  
[https://github.com/crystal-lang/crystal](https://github.com/crystal-lang/crystal)

Find me online:  
[https://medium.com/@watzon](https://medium.com/@watzon)  
[https://twitter.com/_watzon](https://twitter.com/chrystal_coder)  
[https://github.com/watzon](https://github.com/watzon)  
[https://watzon.me](https://watzon.me)