# Crystal 1.20.0 - Product: Crystal (https://whatsnew.fyi/product/crystal) - Vendor: Crystal Language - Date: 2026-04-17 - Version: 1.20.0 - Original notes: https://github.com/crystal-lang/crystal/releases/tag/1.20.0 - Permalink: https://whatsnew.fyi/product/crystal/releases/1.20.0 What's New is an index, not a publisher: every entry below links to the vendor's own release notes, which are the authoritative source. Entries are labelled where they are hand-curated sample data, pre-releases, or drawn from a secondary source such as a developer blog. Reuse: the summaries, labels and curation here are © What's New. Quote freely with attribution and a link back; wholesale republication of the corpus is not permitted — terms: https://whatsnew.fyi/terms. The vendors' own release notes remain their publishers'. --- - **security** — Fix HTTP::Server is no longer vulnerable to request smuggling - **added** — Add #select and #reject to HashLiteral and NamedTupleLiteral in macros - **changed** — Refine error message for unsupported named arguments in macros - **added** — Add short option bundling for OptionParser - **added** — Add Kernel TLS support to custom OpenSSL::BIO - **added** — Add IO#read_greedy - **added** — Add FileUtils#rm_f - **added** — Add IO::PrefixSuffixBuffer for capturing truncated streams - **changed** — Support LLVM 22.1 and 23.0 - **added** — Add Sec-WebSocket-Protocol checks to HTTP::WebSocket::Protocol - **added** — Add support for Sec-WebSocket-Protocol to HTTP::WebSocketHandler - **added** — Add HTTP::Response#content_type and #content_length as convenient accessors - **added** — Detect OAuth error in payload - **added** — Add Fiber::ExecutionContext::ThreadPool - **added** — Add Pointer#align_up and #align_down - **changed** — Detach execution context scheduler from running thread during blocking syscall - **added** — Forward API docs for properties in record macro - **added** — Add Crystal::Lock - **added** — Add io_uring event loop for Linux - **changed** — Use FdLock on all targets - **added** — Add Process.new with args instead of command, args - **added** — Add Process.run(args) without command - **added** — Add Process.run? - **added** — Add Process.capture - **added** — Add StringScanner#scan, #check, and #skip overloads for Int - **added** — Add StringScanner#peek_behind - **added** — Add convenience methods to StringScanner - **changed** — Improve cursor window format in StringScanner#inspect - **changed** — Prefer modern linker (mold or lld) - **added** — Add @[TargetFeature] annotation - **added** — Parse ProcNotation with empty arg parenthesis: () -> - **added** — Add --base-path for crystal docs - **fixed** — Fix decode gzip MTIME as UInt32 - **changed** — OpenSSL sockets shouldn't flush on read - **fixed** — Fix typo in digest.cr - **fixed** — Fix MIME.parse_media_type invalid character check ###### Security ###### stdlib - _(networking)_ Fix `HTTP::Server` is no longer vulnerable to request smuggling ([GHSA-wqh5-7w63-pm68]) [GHSA-wqh5-7w63-pm68]: https://github.com/crystal-lang/crystal/security/advisories/GHSA-wqh5-7w63-pm68 ###### Features ###### lang - _(macros)_ Add `#select` and `#reject` to `HashLiteral` and `NamedTupleLiteral` ([#16558], thanks @Blacksmoke16) - _(macros)_ Refine error message for unsupported named arguments in macros ([#16576], thanks @hahwul) [#16558]: https://github.com/crystal-lang/crystal/pull/16558 [#16576]: https://github.com/crystal-lang/crystal/pull/16576 ###### stdlib - _(cli)_ Add short option bundling for `OptionParser` ([#16770], thanks @Qard) - _(crypto)_ Add Kernel TLS support to custom `OpenSSL::BIO` ([#16646], thanks @ysbaddaden) - _(files)_ Add `IO#read_greedy` ([#16535], thanks @BlobCodes) - _(files)_ Add `FileUtils#rm_f` ([#12832], thanks @zw963) - _(files)_ Add `IO::PrefixSuffixBuffer` for capturing truncated streams ([#16774], thanks @straight-shoota) - _(llvm)_ Support LLVM 22.1 and 23.0 ([#16631], thanks @HertzDevil) - _(networking)_ Add `Sec-WebSocket-Protocol` checks to `HTTP::WebSocket::Protocol` ([#16600], [#16671], thanks @antondalgren, @straight-shoota) - _(networking)_ Add support for `Sec-WebSocket-Protocol` to `HTTP::WebSocketHandler` ([#16574], thanks @antondalgren) - _(networking)_ Add `HTTP::Response#content_type` and `#content_length` as convenient accessors ([#16712], thanks @CTC97) - _(networking)_ Detect `OAuth` error in payload ([#16634], [#16828], thanks @jgaskins, @Sija) - _(runtime)_ Add `Fiber::ExecutionContext::ThreadPool` ([#15885], [#16750], thanks @ysbaddaden) - _(runtime)_ Add `Pointer#align_up` and `#align_down` ([#16585], thanks @BlobCodes) - _(runtime)_ Detach execution context scheduler from running thread during blocking syscall ([#15871], [#16679], thanks @ysbaddaden) - _(runtime)_ Forward API docs for properties in `record` macro ([#16172], [#16834], thanks @Vici37, @ysbaddaden) - _(runtime)_ Add `Crystal::Lock` ([#16768], thanks @ysbaddaden) - _(runtime)_ Add io_uring event loop (linux) ([#16264], thanks @ysbaddaden) - _(system)_ Use `FdLock` on all targets ([#16569], thanks @ysbaddaden) - _(system)_ Add `Process.new` with `args` instead of `command, args` ([#16681], thanks @straight-shoota) - _(system)_ Add `Process.run(args)` without `command` ([#16739], thanks @straight-shoota) - _(system)_ Add `Process.run?` ([#16738], thanks @straight-shoota) - _(system)_ Add `Process.capture` ([#16773], thanks @straight-shoota) - _(text)_ Add `StringScanner#scan`, `#check`, and `#skip` overloads for `Int` ([#16557], thanks @jneen) - _(text)_ Add `StringScanner#peek_behind` ([#16593], thanks @jneen) - _(text)_ Add convenience methods to `StringScanner` ([#16595], thanks @jneen) - _(text)_ Improve cursor window format in `StringScanner#inspect` ([#16594], thanks @jneen) [#12832]: https://github.com/crystal-lang/crystal/pull/12832 [#15871]: https://github.com/crystal-lang/crystal/pull/15871 [#15885]: https://github.com/crystal-lang/crystal/pull/15885 [#16172]: https://github.com/crystal-lang/crystal/pull/16172 [#16264]: https://github.com/crystal-lang/crystal/pull/16264 [#16535]: https://github.com/crystal-lang/crystal/pull/16535 [#16557]: https://github.com/crystal-lang/crystal/pull/16557 [#16569]: https://github.com/crystal-lang/crystal/pull/16569 [#16574]: https://github.com/crystal-lang/crystal/pull/16574 [#16585]: https://github.com/crystal-lang/crystal/pull/16585 [#16593]: https://github.com/crystal-lang/crystal/pull/16593 [#16594]: https://github.com/crystal-lang/crystal/pull/16594 [#16595]: https://github.com/crystal-lang/crystal/pull/16595 [#16600]: https://github.com/crystal-lang/crystal/pull/16600 [#16631]: https://github.com/crystal-lang/crystal/pull/16631 [#16634]: https://github.com/crystal-lang/crystal/pull/16634 [#16646]: https://github.com/crystal-lang/crystal/p _[Truncated at 4000 characters — full notes: https://github.com/crystal-lang/crystal/releases/tag/1.20.0]_