---
title: Crystal 1.9.0 is released!
version: 1.9.0
summary:
thumbnail: +
author: straight-shoota
---

We are delivering a new Crystal release with several bugfixes and improvements.

Pre-built packages are available on [GitHub Releases](https://github.com/crystal-lang/crystal/releases/tag/1.9.0)
and our official distribution channels.
See [crystal-lang.org/install](https://crystal-lang.org/install/) for
installation instructions.

## Stats

This release includes [167 changes since 1.8.2](https://github.com/crystal-lang/crystal/pulls?q=is%3Apr+milestone%3A1.9.0)
by 27 contributors. We thank all the contributors for all the effort put into
improving the language! ❤️

## Changes

Below we list the most remarkable changes in the language, compiler and stdlib.
For more details, visit the [changelog](https://github.com/crystal-lang/crystal/releases/tag/1.9.0).

### Breaking: Big number comparisons with floats

Comparisons of Big number types against floats were fixed to respect special
values such as `NAN`. As a result, the implementation of the comparison operator
`#<=>` between `Big*` (`BigDecimal`, `BigFloat`, `BigInt`, `BigRational`) and
`Float::Primitive` (`Float32`, `Float64`) number types is now nilable.
When invoking these comparisons, `Nil` values must be handled explicitly.

### Windows

The compiler and standard library take a big step improving Windows support.
Only few outstanding issues remain and we expect them to be resolved in the
following months.

Most notable features are a GUI installer (available in the [release artifacts](https://github.com/crystal-lang/crystal/releases/tag/1.9.0))
and dynamic linking of DLLs (currently available via compiler flag
`-Dpreview_dll`).

More details and additional features are listed in a separate post about
[Windows support in Crystal 1.9](/2023/07/06/windows-support-1.9/).

### Language

There are two new macros in the language:

* `ASTNode#warning` is similar to `#raise` but only creates a warning ([#13262](https://github.com/crystal-lang/crystal/pull/13262)).
* `::print` is similar to `::puts` but without the trailing newline ([#13336](https://github.com/crystal-lang/crystal/pull/13336)).

### Standard library

Default interrupt handlers are now in place to trigger `at_exit` handlers
if the process is interrupted ([#13568](https://github.com/crystal-lang/crystal/pull/13568)).

Instead of a single boolean parameter, file matching behaviour of `Dir.glob`
is controlled by `File::MatchOptions` with portable options ([#13550](https://github.com/crystal-lang/crystal/pull/13550)).

The stdlib spec suite makes good use of the spec helper `assert_prints` and it's
now available for user specs as well ([#13599](https://github.com/crystal-lang/crystal/pull/13599)).

There's a new method `Regex#match!` with a non-nilable return type
(`Regex::MatchData`) which is helpful if the regex is expected to match.
`regex.match!(x)` is a convenient replacement for `regex.match(x).not_nil!` ([#13285](https://github.com/crystal-lang/crystal/pull/13285)).

All methods accepting a `Regex` for matching now also have a parameter for
`Regex::MatchOptions` ([#13353](https://github.com/crystal-lang/crystal/pull/13353)).

### Compiler

A new compiler command `crystal clear_cache` offers a convenient way to clean
the compiler cache ([#13553](https://github.com/crystal-lang/crystal/pull/13553)).

This release adds support for LLVM 16 ([#13181](https://github.com/crystal-lang/crystal/pull/13181)).

The docs generator now features dark mode ([#13512](https://github.com/crystal-lang/crystal/pull/13512))
and improved support for small viewports ([#13515](https://github.com/crystal-lang/crystal/pull/13515)).

### Deprecations

* `Dir.[]` with `match_hidden` parameter: Use the overload with a `match`
  parameter instead.
* `Dir.glob` with `match_hidden` parameter: Use the overload with a `match`
  parameter instead.
* `LLVM::Module#write_bitcode_with_summary_to_file`: ThinLTO is no longer
  supported; use `#write_bitcode_to_file` instead.
* `LLVM::FunctionPassManager`: The legacy pass manager was removed in LLVM 17.
  Use `LLVM::PassBuilderOptions` instead.
* `LLVM::FunctionPassManager::Runner`: The legacy pass manager was removed in
  LLVM 17. Use `LLVM::PassBuilderOptions` instead.
* `LLVM::Module#new_function_pass_manager`: The legacy pass manager was removed
  in LLVM 17. Use `LLVM::PassBuilderOptions` instead.
* `LLVM::ModulePassManager`: The legacy pass manager was removed in LLVM 17.
  Use `LLVM::PassBuilderOptions` instead.
* `LLVM::PassManagerBuilder`: The legacy pass manager was removed in LLVM 17.
  Use `LLVM::PassBuilderOptions` instead.
* `LLVM::PassRegistry`: The legacy pass manager was removed in LLVM 17. Use
  `LLVM::PassBuilderOptions` instead.
