---
title: Crystal 0.30.0 released!
version: 0.30.0
summary: Crystal has a new development release.
thumbnail: +
author: bcardiff
comment_href: https://disqus.com/home/discussion/crystal-lang/crystal_0300_released/
---

[Crystal 0.30.0](https://github.com/crystal-lang/crystal/releases/tag/0.30.0) has been released!

This release comes with some language changes, compiler features, and std-lib improvements.  There is some work-in-progress related to multi-threading in other branches, they are moving forward and we are eager to share them as a whole.

There are [139 commits since 0.29.0](https://github.com/crystal-lang/crystal/compare/0.29.0...0.30.0) by 28 contributors.

Let’s review some highlights in this release. But don't miss the rest of the [release changelog](https://github.com/crystal-lang/crystal/releases/tag/0.30.0) which has a lot of valuable information.

## Language changes

The language now checks that the return type of an abstract method is obeyed. This means that in an implementing type you need to annotate _explicitly_ the return type if the abstract method is also annotated.

The following is now an error

```crystal
abstract class Foo
  abstract def foo : String
end

class Bar < Foo
  def foo
    1
  end
end
```

You will need to declare `Bar#foo` as `def foo : String` which makes the underlying issue more evident: `Bar#foo` was wrongly trying to return an `Int32` instead of a `String`.

You don’t need to copy and paste it. A subtype can be used.

```crystal
class Parent; end
class Child < Parent; end

abstract class Foo
  abstract def foo : Parent
end

class Bar < Foo
  def foo : Child
    Child.new
  end
end
```

Finally, if you forget to implement some abstract method the compiler will let you know. Even on generic types and modules.

```crystal
class Foo
  include Enumerable(Int32)
end
```

<br/>

```shell
In src/enumerable.cr:37:16

 37 | abstract def each(&block : T -> _)
                   ^---
Error: abstract `def Enumerable(T)#each(&block)` must be implemented by Foo
```

Since this change is likely to break a good amount of code it is introduced as a warning. Build your project with `--warnings=all` to be ready for when this is switched from a warning to a real compile-time error. Read more about this feature in [#7956](https://github.com/crystal-lang/crystal/pull/7956), [#7999](https://github.com/crystal-lang/crystal/pull/7999), and [#8010](https://github.com/crystal-lang/crystal/pull/8010).

### Syntax changes

A small breaking-change syntax wise is that ranges can not span across lines since [#7888](https://github.com/crystal-lang/crystal/pull/7888).

### Macros

There are a couple of new macro methods to extract arguments of `Annotations` in [#7694](https://github.com/crystal-lang/crystal/pull/7694). For all metaprogramming lovers, this would be good stuff. As usual, metaprogramming is not something to abuse.

The API to work with AST nodes of paths and types had some polishing that will bring some fewer headaches. Read more in [#7970](https://github.com/crystal-lang/crystal/pull/7970).

## Compiler

Support for LLVM 7 was a long debt. We finally paid it together with support for LLVM 8. Read more about it in [#7987](https://github.com/crystal-lang/crystal/pull/7987) and [#7986](https://github.com/crystal-lang/crystal/pull/7986). In case you want to contribute in two months with the LLVM 9 support ;-)

There are a couple of bug-fixes related to [top-level private const scope](https://github.com/crystal-lang/crystal/pull/7907), [annotation lookup on generic types](https://github.com/crystal-lang/crystal/pull/7891) and other corner cases.

## Distribution

In case you missed the [news](https://crystal-lang.org/2019/06/19/snapcraft-summit-montreal.html), the nightly Linux release is available in [snapstore.io](https://snapcraft.io/crystal) and in TravisCI as `crystal: nightly` in your `travis.yml`. This was automated in [#7893](https://github.com/crystal-lang/crystal/pull/7893).

For macOS official packages (ie: the one that you can download from GitHub) we are [now using](https://github.com/crystal-lang/crystal/pull/7994) LLVM 6.0.1. Don’t ask what has been used up until today.

For Homebrew, LLVM 8.0.0 is used from now on.

## Standard library

There was a need for a breaking-change in `UUID`: the method `UUID#to_slice` was removed because it exposed a pointer to the underlying memory representation and doing that in a stack allocated value is error-prone. Use `UUID#bytes` instead, that returns a `StaticArray(UInt8, 16)`. Read more at [#7901](https://github.com/crystal-lang/crystal/pull/7901).

Boxing of values using `Box` is used for some [C callbacks](https://crystal-lang.org/reference/syntax_and_semantics/c_bindings/callbacks.html) and some low-level structures. Thanks to [#8016](https://github.com/crystal-lang/crystal/pull/8016) the boxing of `nil` and reference types is now lighter.

`Benchmark.memory` is now available to measure just memory usage. Read more at [#7835](https://github.com/crystal-lang/crystal/pull/7835).

Every now and then some sample code in the docs are outdated. There is a tool made and run regularly to keep them in good shape. Luckily [#8003](https://github.com/crystal-lang/crystal/pull/8003) was not as big as other past iteration. Check [maiha/crystal-examples](https://github.com/maiha/crystal-examples) to see how this is done!

### Serialization

JSON serialization can handle numeric keys, so `Hash(Int32, String).from_json` works. Read more at [#7944](https://github.com/crystal-lang/crystal/pull/7944).

YAML deserialization handles `String` as the last option if the expected type is a union. Since anything can be a `String` that make sense. Read more at [#7938](https://github.com/crystal-lang/crystal/pull/7938)

Finally there is a breaking-change regarding the API on the JSON parser. The usage of symbols for the parser state was replaced by enums in [#7966](https://github.com/crystal-lang/crystal/pull/7966).

### Networking

`URI.escape` and `URI.unescape` are deprecated and you will need to choose between `URI.encode_www_form`/`URI.decode_www_form` and `URI.encode`/`URI.decode`. This allows you to choose how to handle reserved chars. Read more at [#7997](https://github.com/crystal-lang/crystal/pull/7997).

The parsing of the HTTP protocol got some performance optimizations in [#8002](https://github.com/crystal-lang/crystal/pull/8002) and [#8009](https://github.com/crystal-lang/crystal/pull/8009). This might improve the performance of `HTTP::Server` in your apps.

### System

There is an initial API to work with users and groups in [`System::User`](https://crystal-lang.org/api/0.30.0/System/User.html) and [`System::Group`](https://crystal-lang.org/api/0.30.0/System/Group.html). Read more at [#7725](https://github.com/crystal-lang/crystal/pull/7725).

## Other news

Snapcraft 3.7 has been released and that means that the [Crystal plugin](/2019/06/19/snapcraft-summit-montreal/#packaging-your-crystal-app-as-a-snap) can be used out of the box.

## Next steps

Please update your Crystal and report any issues. We will keep moving forward and start the development focusing on 0.31.

Once again, check your code with `--warnings=all`. This will help in the migration of your codebase and will probably push some feedback about that tool. Some future language changes were introduced in this release as warnings for a smooth migration. But, unless you use `--warnings=all` you will not discover them.

It will also be helpful if your shards are run against Crystal nightly releases. Either Docker or Snap are the current channels to get them easily. This will help to reduce the friction of a release while checking if the ecosystem is in good shape.

Stay tuned!

> **THANKS:**
> The development is possible thanks to the community's effort, [84codes](https://www.84codes.com/)' support, and every [supporter](https://crystal-lang.org/sponsors).
