Gleam(グリーム)は、Erlang仮想マシン(BEAM)とJavaScriptランタイムの両方で動く、静的型付けの関数型プログラミング言語です。2024年3月4日にv1.0.0が出て、2026年10月18日時点の最新版はv1.19.2(2026年10月12日)です。名前はErlang VMの「BEAM」と韻を踏み、意味も近い英単語のgleam(かすかな光)から取られています。懸賞キャンペーンサービスのgleam.ioとは別のものです。この記事では、Gleam 1.19.2で実際に動かしたコードと出力を示しながら、インストール、構文、テスト、Webサーバー、OTPによる並行処理、JavaScriptターゲットの制約、Elixirとの違いまでを整理します。
まとめ
- 正体:BEAMとJavaScript(ECMAScript 2022以上)にコンパイルされる型安全な関数型言語。型が合わないコードはビルドが通らない。
- 最新版:v1.19.2(2026年10月12日)。v1.19ではErlang向けの出力形式が変わり、手元の計測ではクリーンビルドが約2割短くなった。
- 試す・導入する:公式のLanguage Tourならインストール不要でブラウザ上で動かせる。macOSは
brew install gleamでErlangとrebar3も入る。v1.18以降はErlang/OTP 29と28に対応。 - テストとWeb:
gleam testと言語組み込みのassertでテストを書ける。Webサーバーは Wisp+Mist で、ルーティングはパターンマッチで書く。 - 並行処理:
gleam_otpのactorで、メッセージの型までコンパイル時に検査される。ただしErlangターゲット専用。 - JavaScript:TypeScript定義は
typescript_declarations = trueを設定したときだけ出る。整数の安全な範囲は−(2^53−1)〜2^53−1で、範囲外では丸めが起こり得る。 - 向き不向き:型クラス・マクロ・例外・可変状態を持たない小さな言語。Elixirのマクロ前提のライブラリやホットコードアップグレードを多用する現場には合わない。
Gleamの特徴と設計方針
静的型と型推論によるコンパイル時の検査
Gleamは変数や関数の型を推論し、型が合わなければコンパイルエラーにします。型注釈は省略できます。Erlang VM上の言語でありながら、実行前に型の不整合をコンパイルエラーとして検出できる点が特徴です。後述のactorに整数を渡すべき場所へ文字列 "4" を渡すと、v1.19.2は次のエラーを出してビルドを止めます。
error: Type mismatch
24 │ process.send(counter, Add("4"))
│ ^^^
Expected type:
Int
Found type:
String
もう一つの特徴は、null や例外を言語に持たないことです。値が無い可能性は Option、失敗する可能性は Result 型で表し、case 式ですべての分岐を書かないとコンパイラが警告ではなくエラーを出します(網羅性検査)。
Gleamで追加予定のない言語機能
Gleam公式FAQは「Gleamは常に小さくまとまった言語であり続ける」とし、今後も追加しない機能を列挙しています。主なものは次のとおりです。
- 例外によるエラー処理、関数・演算子のオーバーロード、省略可能な引数
- Lisp風のマクロ、型クラスやトレイト、オブジェクト指向
- ミュータブルな変数(データ構造はすべてイミュータブル)
v1.0の告知では、この小ささを「午後のうちに学べる(learn in an afternoon)」と表現しています。Haskellの型クラスやRustのトレイトのような抽象化を期待すると物足りなく感じます。型クラスやLisp風マクロを前提とする設計は使えないため、関数やカスタム型を組み合わせて表現します。
ErlangとJavaScriptの2つのコンパイルターゲット
同じGleamのコードを、Erlangの .beam バイトコードにも、JavaScriptのESモジュール(.mjs)にもコンパイルできます。ターゲットはプロジェクト作成時の --template(erlang か javascript、既定は erlang)か、実行時の --target で選びます。Erlangターゲットでは既存のErlang・Elixirのライブラリを使え、JavaScriptターゲットの出力はNode.js・Deno・Bunやブラウザで動きます。作者はLouis Pilfoldで、最初の公開版v0.1は2019年4月に出ました。コンパイラ自体はRustで書かれており、試作段階のErlang版から「静的型が無くてリファクタリングが遅く誤りやすかった」ためにRustへ書き直されたと公式FAQが説明しています。
インストールと最初のプロジェクト
Language Tour・Playground・Exercismによる学習
最初に構文を触るだけなら、インストールは要りません。公式のGleam Language Tourは、画面のコードを書き換えると、ブラウザの中でGleamをJavaScriptにコンパイルして実行し、出力とコンパイルエラーを下に表示します。言語の全機能を順に解説する対話式の教材で、ほかの言語の経験があればこれだけで実用的なプログラムを書けるようになる、と案内しています。1ファイルを自由に試すGleam Playgroundもあります。演習問題で手を動かしたい場合は、ExercismのGleamトラックに122問が用意されています。Language TourとPlaygroundのブラウザ内実行はJavaScriptターゲットのため、Erlang専用の gleam_otp は動かせません。Exercismのオンライン演習は別方式で、提出コードをサーバー側のテストランナーで実行します。
OS別のインストールコマンド
公式のインストール手順(gleam.run/install)が案内する主なコマンドは次の表のとおりです。Erlangターゲットで実行するにはErlang/OTPが必要です。rebar3は、Erlangで書かれた依存パッケージをコンパイルするときに使われます。HomebrewのGleamパッケージはErlangとrebar3を依存として一緒に入れるので、macOSならコマンド1つで揃います。
| 環境 | Gleam | Erlang |
|---|---|---|
| macOS(Homebrew) | brew install gleam | 依存として同時に導入 |
| Windows(winget) | winget install –id Gleam.Gleam | winget install –id Erlang.ErlangOTP |
| Windows(Scoop) | scoop install main/gleam | scoop install main/erlang |
| Arch Linux | sudo pacman -S gleam erlang rebar3 | 同じコマンドで導入 |
| Alpine Linux | sudo apk add gleam erlang rebar3 | 同じコマンドで導入 |
パッケージマネージャーを使わない場合は、GitHubのリリースページからビルド済みバイナリを取得できます。公式に継続テストされているのはLinux・macOS・Windowsのx86_64とaarch64です。バイナリだけを入れた環境でrebar3が無いと、Erlang製の依存を含むプロジェクト(後述のWispなど)はビルドの途中で「rebar3をインストールしてください」という案内を出して止まります。
対応するErlang/OTPのバージョン
GleamのErlangターゲットは、各リリース時点で最新2つのErlang/OTPメジャーバージョンを対象にしています。古いOTPを使い続けている環境では、Gleamを上げる前に確認が必要です。
| Gleam | 対応するErlang/OTP |
|---|---|
| v1.18以降(v1.19を含む) | OTP 29・28 |
| v1.11〜v1.17 | OTP 28・27 |
| v1.2〜v1.10 | OTP 27・26 |
| v1.0〜v1.1 | OTP 26・25 |
gleam new からgleam run までの流れ
インストール後は gleam --version で版を確認し、gleam new でプロジェクトを作ります。生成されるのは gleam.toml、src/<名前>.gleam、test/<名前>_test.gleam で、依存には gleam_stdlib、テスト用に gleeunit が入ります。
$ gleam --version
gleam 1.19.2
$ gleam new my_app
$ cd my_app
$ gleam run
Hello from my_app!
$ gleam run --target javascript # 同じコードをNode.jsで実行
Hello from my_app!
日常的に使うサブコマンドは次のとおりです。パッケージはErlang・Elixirと共通のレジストリHexから取得します。
| コマンド | 用途 |
|---|---|
| gleam add <pkg> | Hexから依存を追加 |
| gleam run / gleam run -m <module> | 実行(モジュール指定可) |
| gleam build / gleam check | ビルド/型検査のみ |
| gleam test | テスト実行 |
| gleam format | 公式フォーマッタ |
| gleam shell | Gleamのコードを読み込んだErlang REPL |
| gleam export escript | 単一ファイルの実行物を生成(v1.17〜) |
エディタとLanguage Server
Language Serverはコンパイラに組み込まれており、gleam lsp で起動します。公式手順はVS Code・Neovim・Helix・Zed・Sublime Text・Emacs・Vimの設定を案内しており、Helixは追加設定なしで動きます。v1.18ではレコードのフィールドについても定義へのジャンプ・参照検索・リネームが使えるようになりました。
Gleamの基本構文と実行結果
カスタム型・case式・Resultを使う例
カスタム型、case 式、Result、パイプ演算子 |>、use 式をまとめて使う例です。Gleam 1.19.2・gleam_stdlib 1.0.5で、ErlangとJavaScriptの両ターゲットで同じ結果になることを確認しました。先ほど作ったmy_appプロジェクトの src/my_app.gleam を次の内容に置き換えます。
import gleam/int
import gleam/io
import gleam/list
import gleam/result
pub type Shape {
Circle(radius: Float)
Rect(width: Float, height: Float)
}
pub fn area(shape: Shape) -> Float {
case shape {
Circle(r) -> 3.14159 *. r *. r
Rect(w, h) -> w *. h
}
}
pub fn parse_age(input: String) -> Result(Int, String) {
use n <- result.try(int.parse(input) |> result.replace_error("数値ではありません"))
case n {
n if n < 0 -> Error("負の値です")
n -> Ok(n)
}
}
pub fn main() -> Nil {
let total =
[Circle(1.0), Rect(2.0, 3.0)]
|> list.map(area)
|> list.fold(0.0, fn(acc, a) { acc +. a })
echo total
let _ = echo parse_age("42")
let _ = echo parse_age("-1")
let _ = echo parse_age("abc")
io.println("done")
}
出力は 9.14159、Ok(42)、Error("負の値です")、Error("数値ではありません")、done です(echo は値の前にファイル名と行番号を標準エラーへ出します)。読むときの要点は3つあります。
- 浮動小数点の演算子は
*.や+.で、整数の*+と区別される。IntとFloatは暗黙に変換されない。 use n <- result.try(...)は、失敗ならErrorをそのまま返し、成功なら中身をnに束縛して続きを実行する。ネストしたcaseを平らにする構文。caseのifはガード。Shapeに新しいバリアントを足すと、areaの網羅漏れがコンパイルエラーになる。
古い記事でよく見る io.debug は、標準ライブラリ0.59.0(2025年4月)で非推奨になり、0.61.0(2025年6月)で削除されました。gleam_stdlib 0.61.0以降で使うと「gleam/io に debug が無い」というコンパイルエラーになります。デバッグ出力には、v1.9で入った echo キーワードを使います。
ループと再代入が無いことによる書き方の違い
Gleamには for や while のようなループ構文が無く、繰り返しは list.map や list.fold などの関数か、再帰で書きます。変数の値を書き換える演算子もありません。v1.19.2で n += 1 と書くと、次の専用のエラーが出ます。v1.18.1では「演算子の右側に値が無い」という構文エラーだけだったので、他言語から来た人が原因を掴みやすくなりました。
error: Syntax error
3 │ n += 1
│ ^^ Unknown operator
Gleam is an immutable language and does not have any operators that
change the value of an existing variable. You might want to create a
new variable with the same name as the previous one:
let wibble = 10
let blobby = wibble
let wibble = wibble + 20
エラー文が示すとおり、同じ名前で let し直す(シャドーイング)のがGleamの書き方です。元の値は書き換わらず、新しい変数が作られます。不変性や高階関数という考え方そのものは関数型プログラミングの解説記事で整理しています。
テストとWebサーバーの書き方
gleam test と assert によるテスト
gleam new で作ったプロジェクトには、テストランナーのgleeunitが最初から入っています。test ディレクトリにある _test で終わる名前の公開関数がテストとして実行されます。真偽値の検査には、v1.11で言語に加わった assert キーワードを使います。let assert は、パターンに一致すれば変数に束縛し、一致しなければその場で失敗させる構文です。前章の area と parse_age を検査するため、生成済みの test/my_app_test.gleam を次の内容に置き換えます。
import gleeunit
import my_app
pub fn main() -> Nil {
gleeunit.main()
}
pub fn area_test() {
assert my_app.area(my_app.Rect(2.0, 3.0)) == 6.0
}
pub fn parse_age_test() {
let assert Ok(age) = my_app.parse_age("42")
assert age == 42
assert my_app.parse_age("-1") == Error("負の値です")
}
gleam test と gleam test --target javascript のどちらでも「2 passed, no failures」になりました。期待値をわざと 41 に変えると、失敗した式と左右の値が表示されます。
assert test/my_app_test.gleam:14
test: my_app_test.parse_age_test
code: assert age == 41
left: 42
right: 41
info: Assertion failed.
1 passed, 1 failures
WispとMistによる最小Webサーバーの実装
サーバー側のWeb開発では、Webフレームワーク Wisp(v2.2.2)とHTTPサーバー Mist(v6.0.3)の組み合わせが定番です。Wispは専用のルーターを持たず、URLのパスを文字列のリストにしてパターンマッチで振り分けます。公式サンプルのコメントは、この方が速く、型安全で、独自のDSLを覚えなくて済むと説明しています。この例用に gleam new web と cd web で別プロジェクトを作ります。そこで gleam add wisp mist gleam_http gleam_erlang を実行し、src/web.gleam に次のコードを書きます。
import gleam/erlang/process
import gleam/http.{Get}
import mist
import wisp.{type Request, type Response}
import wisp/wisp_mist
fn handle_request(req: Request) -> Response {
case wisp.path_segments(req) {
[] -> {
use <- wisp.require_method(req, Get)
wisp.ok() |> wisp.string_body("Hello, Gleam!")
}
["users", id] -> wisp.ok() |> wisp.string_body("user " <> id)
_ -> wisp.not_found()
}
}
pub fn main() -> Nil {
wisp.configure_logger()
let assert Ok(_) =
wisp_mist.handler(handle_request, wisp.random_string(64))
|> mist.new
|> mist.port(8000)
|> mist.start
process.sleep_forever()
}
gleam run で起動し、curlで確かめた結果は次のとおりです(手元では空いていた別のポート番号に変えて計測しました)。
GET /は200で「Hello, Gleam!」GET /users/42は「user 42」(パスの一部が変数idに束縛される)- 未定義のパスは404、
POST /はrequire_methodによって405
アダプターの wisp_mist は別パッケージではなく、Wisp 2系では wisp/wisp_mist モジュールとして同梱されています。import wisp_mist と書くと「Unknown module」のエラーになり、wisp/wisp_mist を使うよう案内されます。依存のうちHTTP/2用の hpack_erl はErlangで書かれているため、ビルドにはrebar3が必要でした。
BEAM上の並行処理とOTP
型付きactorの書き方
Erlangの強みである軽量プロセスと監視ツリー(OTP)は、パッケージ gleam_otp(v1.3.0)と gleam_erlang(v1.3.0)から使います。gleam_otp のドキュメントは、actorをErlangの gen_server やElixirの GenServer に近いものとしつつ「完全に型付けされたインターフェース」を持つ点が違うと説明しています。次はカウンターのactorです。プロジェクト内で gleam add gleam_otp gleam_erlang を実行し、次のコードを src/counter.gleam に保存してください。この例はErlang専用なので、JavaScript用の例とは別のプロジェクトで試します。
import gleam/erlang/process.{type Subject}
import gleam/otp/actor
pub type Message {
Add(Int)
Get(reply_to: Subject(Int))
}
fn handle(count: Int, msg: Message) -> actor.Next(Int, Message) {
case msg {
Add(n) -> actor.continue(count + n)
Get(reply_to) -> {
process.send(reply_to, count)
actor.continue(count)
}
}
}
pub fn main() -> Nil {
let assert Ok(started) =
actor.new(0) |> actor.on_message(handle) |> actor.start
let counter = started.data
process.send(counter, Add(3))
process.send(counter, Add(4))
echo process.call(counter, waiting: 100, sending: Get)
Nil
}
gleam run -m counter の出力は 7 です。宛先の Subject(Message) が受け取れるメッセージの型を持っているため、Add("4") のような誤送信は、前章で示したとおりコンパイル時に止まります。Erlang・Elixirでは実行時にしか分からない種類の誤りです。
ホットコードアップグレードの扱い
Erlangのコード差し替え機能自体はGleamでも動きます。ただし公式FAQによれば、稼働中のコードの型を知る手段が無いため、差し替えそのものは型検査されません。Gleam向けのOTPライブラリはアップグレードのしやすさより型安全を優先して設計されている、とFAQは明記しています。無停止のホットアップグレードを運用の柱にしているシステムでは、この点が採用判断の分かれ目になります。
JavaScriptターゲットの使い方と制約
ビルドとTypeScript型定義
gleam build --target javascript の出力は build/dev/javascript/<パッケージ名>/ に .mjs として並びます。gleam run と gleam test が直接扱えるランタイムはNode.js・Deno・Bunで、既定はNode.jsです。TypeScriptの型定義(.d.mts)は既定では生成されず、gleam.toml に次の設定を書いたときだけ出力されます。
[javascript]
typescript_declarations = true
生成された定義では、カスタム型のJavaScriptクラスのコンストラクタに @deprecated が付き、代わりに Shape$Circle(radius)(生成)、Shape$isCircle(value)(判定)、Shape$Circle$radius(value)(フィールド取得)という関数が出力されます。これはv1.13で導入された「Gleamのデータを外部から扱うための公式API」で、JavaScript側からGleamの値を作る・調べるときはこちらを使います。v1.19では判定関数に型を絞り込むオーバーロードが加わりました。Full(value) と Empty を持つ型 Box で比べると、v1.18.1の定義は value is Box$<unknown> を返す1本だけでしたが、v1.19.2では次の行が増え、if の中で Full として扱えます。
export function Box$isFull<DPN>(value: Box$<DPN>): value is Full<DPN>;
型引数の名前(ここでは DPN)はコンパイラが自動で付けるもので、ビルドによって変わることがあります。
v1.16からは javascript.source_maps = true でソースマップも出せ、ブラウザのデバッガでGleamのソース行を追えます。
@externalによるJavaScript・Erlangとの連携
他言語の関数は @external 属性で型を付けて取り込みます。ターゲットごとに実装を書き分けられるので、同じ関数名で両方に対応できます。
@external(javascript, "./now_ffi.mjs", "now")
@external(erlang, "os", "system_time")
pub fn now() -> Int
pub fn main() -> Nil {
echo now() > 0
Nil
}
JavaScript側は src/now_ffi.mjs に export function now() { return Date.now(); } を置くだけです。両ターゲットで True が出ることを確認しました。ただし、この例が確かめるのは戻り値が正であることだけです。JavaScriptのDate.now()はミリ秒、Erlangのos:system_time()はnative単位なので、共通の時刻APIにする場合は単位を統一する必要があります。また外部関数の型は、Gleamが宣言を信じるだけで検査はしません。実装が宣言と違う型を返すと、Gleamの型安全はそこで崩れます。
JavaScriptで使えないものと数値の制約
最も影響が大きいのは、gleam_otp と gleam_erlang がErlangターゲット専用であることです。前章のactorを --target javascript でビルドすると、次のエラーで止まります。
error: Unsupported target
This value is not available as it is defined using externals, and there is
no implementation for the JavaScript target.
数値も違います。JavaScriptターゲットの Int はJavaScriptのnumber型なので、整数を安全に扱える範囲は−(2^53−1)〜2^53−1で、範囲外では整数によって丸めが発生します。int.to_string(9_007_199_254_740_993) を出力すると、Erlangでは 9007199254740993、JavaScriptではコンパイル時の警告(Int is outside JavaScript’s safe integer range)のうえ 9007199254740992 になりました。IDや金額を大きな整数で扱うコードは、JavaScriptターゲットで動かす前に範囲を確認してください。
フロントエンド開発とLustre
ブラウザ向けのUIには、Elmと同じModel・Update・Viewの構成を取るフレームワーク Lustre(v5.7.1・2026年7月13日)がよく使われます。既存のReactアプリにGleamを混ぜるなら、ビジネスロジックをGleamで書いて .mjs と型定義を読み込む形になります。Elm Architecture自体の考え方はElm(プログラミング言語)の解説記事で詳しく扱っています。
Elixir・Elm・OCaml・Rustとの違い
| 言語 | 実行環境 | 型 | Gleamとの主な違い |
|---|---|---|---|
| Gleam | BEAM・JS | 静的・推論 | - |
| Elixir | BEAM | 段階的(推論中心) | マクロ・Phoenix |
| Elm | JS(主にブラウザ) | 静的・推論 | ブラウザUI中心 |
| OCaml | ネイティブ・JS | 静的・推論 | ファンクタ・可変値あり |
| Rust | ネイティブ | 静的 | 所有権・トレイト |
Elixirとの違いと相互運用
同じBEAM上の言語で、最も比較されるのがElixirです。Elixirはバージョンごとに型検査の範囲を広げており、1.18で関数呼び出しの型検査、1.19でプロトコルと無名関数の型推論が加わりました。2026年6月3日公開のElixir v1.20では、型注釈なしですべての言語構文から関数定義の型を推論し、確実なバグやデッドコードを見つけるようになりました。ただし公式ドキュメントは「ユーザーが書く型シグネチャは今後のリリースで予定」としており、現時点で開発者が型に触れるのは主にコンパイラの警告と診断を通じてです。Gleamは最初から型が言語の中心で、型が合わなければビルドできません。Gleam公式FAQも「2つの型システムは可能な限り異なる」と書いています。
相互運用はできます。Gleamのビルドツールは、Elixirがインストールされていれば、Elixirの依存やソースファイルをGleamプロジェクト内でコンパイルします。ただしElixirのマクロはElixirの外から呼べないため、マクロ前提のAPIは、Elixirで薄いモジュールを書いてからGleamで呼ぶ必要があります。PhoenixのLiveViewで作ったElixirアプリの例はElixir Desktopの解説記事で扱っています。
Elm・OCaml・Rustとの違い
Elmとは構文と「例外もnullも無い」設計思想が近い言語です。ElmはJavaScriptにコンパイルされ、ブラウザ向けUI開発が主用途です(Platform.workerを使えばNode.js上でも動かせます)。GleamはBEAMとJavaScriptを公式ターゲットとし、サーバーやCLIにも対応します。OCamlとは型推論とバリアント型が共通ですが、OCamlにはファンクタや可変の参照があり、Gleamは機能を絞る方向です。Rustとは構文が似ていても、Rustは可変性を制御する低レベルの命令型言語で、GleamはGC付きの関数型言語だと公式FAQは区別しています。型クラスを軸にした抽象化が必要なら、Haskellが得意とする分野の方が合います。
バージョン履歴と1.x系の主な変更
v1.0の告知は「セマンティックバージョニングに従い、後方互換の維持を優先する」とし、例外はセキュリティと健全性の問題だけとしています。リリース周期に決まりは無く、公式の互換性リファレンスによればマイナー版は通常1〜3か月ごと、修正が入るのは原則として最新のマイナー版だけです。
| 版 | 公開日 | 主な変更 |
|---|---|---|
| v0.1 | 2019-04-15 | 最初の公開版 |
| v1.0.0 | 2024-03-04 | 初の安定版 |
| v1.9.0 | 2025-03-09 | echoキーワード |
| v1.11.0 | 2025-06-02 | 単独のassertキーワード |
| v1.13.0 | 2025-10-19 | 外部向けのデータAPI |
| v1.16.0 | 2026-04-24 | JSのソースマップ |
| v1.17.0 | 2026-06-02 | gleam export escript |
| v1.18.0 | 2026-07-29 | LSPのフィールド対応・OTP 29 |
| v1.19.0 | 2026-10-05 | Erlang Abstract Format出力・TSの型ガード |
| v1.19.2 | 2026-10-12 | 不具合修正(現行の最新版) |
v1.19の主な変更点
v1.19の変更履歴で、利用者に関係が大きいのは次の4点です。
- Erlang Abstract Formatへの出力:Erlangターゲットは、テキストのErlangコードではなくErlangの抽象構文(Abstract Format)を出すようになった。生成コードの各行を元のGleamの行へ対応付けられ、一般的なパッケージのコンパイル時間も短くなった。
- リスト全体を受ける
[..x]パターンの非推奨:caseで[..x] -> xと書くと「Deprecated list pattern matching syntax」の警告が出る。単にxと書けばよい。将来のメジャー版で削除される可能性があると明記されている。 - 他言語の演算子への専用エラー:
+=や++を書いたときに、前述の説明つきエラーが出る。 - TypeScript定義の型ガード:前述の
Box$isFullのように、判定関数で型を絞り込める。
出力形式の変更がビルド時間にどう出るかを、前章のWispプロジェクト(依存22パッケージ・Intel Mac・Erlang/OTP 29)のクリーンビルドで3回ずつ測りました。v1.18.1は6.55秒・7.10秒・5.98秒、v1.19.2は5.43秒・5.20秒・5.50秒で、平均は約6.5秒から約5.4秒へ縮みました。依存の規模やマシンで差は変わるので、目安として見てください。v1.19.1と1.19.2は不具合修正だけの版です。
標準ライブラリ gleam_stdlib も2026年4月18日にv1.0.0へ到達しました。これより前のstdlib 0.x系を前提にした解説記事のコードは、io.debug のように削除済みの関数を含むことがあります。
Gleamを採用すべきでない場面
公式FAQは本番利用について「ミッションクリティカルな用途にも使える」と明言しており、公式サイトにはロンドンのマーケティング会社Strand(2024年1月から利用)や、ブラジルのマーケティング分析企業Uncover(2024年4月から利用)の事例が載っています。それでも、次の条件に当てはまるなら別の言語を選ぶ方が安全です。
- Phoenix・Ectoなどマクロ中心のElixir資産に依存している:マクロはGleamから直接呼べず、ラッパーのElixirモジュールが増える。
- ホットコードアップグレードを運用の前提にしている:差し替えは型検査されず、OTPライブラリも型安全を優先した設計。
- JavaScriptターゲットでOTPのような並行処理を期待している:
gleam_otpはErlang専用で、JS側は別の設計が要る。 - 型クラスやLisp風マクロで抽象化したい:公式FAQはこれらを追加予定のない機能として挙げている。
見落としやすい仕様として、整数の0除算は例外にならず 0 を返します。BEAMに無限大の値が無く、Gleamは暗黙の例外を投げないためです。0除算を検出したい箇所では、Result を返す標準ライブラリの関数(int.divide など)を使ってください。BEAMの軽量プロセスとOSスレッドの関係はグリーンスレッドとOSスレッドの違いの記事で扱っています。
Gleamに関するよくある質問
Gleamの読み方と名前の由来は?
「グリーム」と読みます。公式FAQによれば、Erlang VMの名前「BEAM」と韻を踏み、意味も近い英単語から取られています。英単語のgleamは「かすかな光・きらめき」です。
Gleamはインストールせずに試せますか?
試せます。公式のLanguage Tour(tour.gleam.run)とPlayground(playground.gleam.run)は、ブラウザの中でGleamをJavaScriptにコンパイルして実行します。Erlangターゲット専用のOTPの機能は試せないので、actorを動かすにはローカルにインストールしてください。
Gleamのインストールには何が必要ですか?
Gleam本体に加え、Erlangターゲットでの実行にはErlang/OTP、JavaScriptターゲットでの実行にはNode.jsなどのJavaScriptランタイムが必要です。Erlang製の依存を使うならrebar3も要ります。macOSは brew install gleam でErlangとrebar3も入ります。Windowsは winget install --id Gleam.Gleam と winget install --id Erlang.ErlangOTP です。v1.18以降はOTP 29と28に対応しています。
GleamとElixirはどちらを選ぶべきですか?
型でビルド時に誤りを止めたいならGleam、Phoenixなどの成熟したフレームワークとマクロを使いたいならElixirです。同じBEAM上で動くので、Elixirがインストールされていれば、GleamのプロジェクトでElixirの依存やソースをコンパイルして呼び出せます。
GleamはReactやフロントエンド開発で使えますか?
JavaScriptターゲットでブラウザ向けのコードを出力できます。UIはElm風のフレームワークLustreで書くのが一般的です。既存のReactアプリと組み合わせるなら、React側からGleamの出力した関数を呼び出す形になります。
Gleamの最新バージョンはいくつですか?
2026年10月18日時点の最新版はv1.19.2(2026年10月12日公開)です。最新はGitHubのgleam-lang/gleamのリリースページで確認できます。