Why Gleam Installation Sucks (And How to Fix It)
Let me save you some time: Gleam installation is straightforward once you know what breaks. But the official docs assume you understand BEAM, have never installed conflicting language runtimes, and definitely haven't spent the last hour wondering why gleam --version
returns "command not found."
Here's what actually works, with the gotchas nobody mentions.
The Erlang Dependency That Will Fuck You
Gleam needs Erlang/OTP to run. Not optional. Not "recommended." Required.
The problem? If you've ever installed Elixir, Phoenix, or any other BEAM language, you probably have multiple Erlang versions fighting each other. This will bite you later when packages mysteriously fail to compile.
Check what you already have:
erl -version
## Should show Erlang (SMP,ASYNC_THREADS) (BEAM) emulator version X.X
If that command fails, you need Erlang. If it shows version 23 or older, you need to upgrade. Gleam fails with Erlang versions older than 24. Trust me on this one - I spent two hours debugging compiler errors before realizing my Ubuntu had ancient Erlang.
Just Use Package Managers
macOS: Use Homebrew. Period.
brew install gleam
If you already have Erlang from Elixir or whatever, uninstall everything first:
brew uninstall erlang elixir gleam
brew install gleam
Linux: Ubuntu's packages work fine:
sudo apt update && sudo apt install erlang gleam
If that doesn't work for some reason, grab the binary from GitHub releases and drop it in /usr/local/bin/
.
Windows: Use Scoop:
scoop install erlang gleam
Everyone else: Use asdf version manager with the gleam plugin. Works on everything and handles multiple versions nicely.
What Actually Breaks During Installation
"gleam: command not found" - Your PATH is fucked. On macOS, run echo $PATH
and make sure you see /opt/homebrew/bin
(M1/M2) or /usr/local/bin
(Intel). On Linux, /usr/local/bin
should be there. I spent 20 minutes debugging this when I had an old ~/.zshrc that was overriding my PATH.
True story: I once installed Gleam, then spent an hour wondering why it wasn't working. Turns out I had an old alias in my .bashrc that was redirecting gleam
to some Python script from 2019. Check for weird aliases first.
Fix it permanently:
## macOS (add to ~/.zshrc or ~/.bash_profile)
export PATH=\"/opt/homebrew/bin:$PATH\"
## Linux (add to ~/.bashrc)
export PATH=\"/usr/local/bin:$PATH\"
Multiple Erlang versions fighting - This happens if you've installed Elixir, RabbitMQ, or other BEAM tools. Gleam fails with version conflicts. Check what you have:
which erl
ls -la $(which erl)
erl -version # Try to use a recent version
If you see version conflicts, nuke everything and start fresh (takes about 5 minutes):
## macOS
brew uninstall --ignore-dependencies erlang elixir gleam
brew install gleam
## Linux - remove all Erlang packages and reinstall
sudo apt remove erlang* esl-erlang
## Then reinstall from scratch - this breaks RabbitMQ if you have it
Permission errors on Linux - Don't sudo random shit. If you need sudo to install, that's fine, but never run sudo gleam commands. I learned this the hard way when sudo gleam new
created a project owned by root and spent 20 minutes fixing file permissions.
Even better: I once fixed "permission denied" by running sudo gleam run
and then wondered why my compiled binaries wouldn't run normally. Turns out sudo creates cache files owned by root in ~/.gleam. Had to sudo rm -rf ~/.gleam
and start over.
M1/M2 Mac weirdness - If you're getting \"Exec format error\" or \"bad CPU type in executable\", you're running Intel binaries on Apple Silicon. This will waste 30 minutes of your life. Fix it:
arch -arm64 brew install gleam
Your First Project (That Actually Does Something)
Skip the \"Hello World\" bullshit. We're building a CLI tool that fetches data from an API, because that's what you'll actually do in real projects.
gleam new api_client
cd api_client
This creates the standard structure:
- `gleam.toml` - Project config (like package.json but less insane)
src/api_client.gleam
- Your main codetest/api_client_test.gleam
- Tests that might actually pass
Adding Dependencies Without Npm Hell
Gleam's package management is what npm should have been. Add HTTP handling:
gleam add gleam_http gleam_httpc gleam_json
This updates gleam.toml
with exact versions. No lockfile conflicts, no rm -rf node_modules
, no "works on my machine" dependency resolution bullshit.
Write Code That Compiles (First Try)
Replace src/api_client.gleam
with something useful:
import gleam/http/request
import gleam/httpc
import gleam/io
import gleam/json
import gleam/result
pub fn main() {
case fetch_user_data(1) {
Ok(user) -> io.println(\"User: \" <> user)
Error(msg) -> io.println(\"Failed: \" <> msg)
}
}
fn fetch_user_data(user_id: Int) -> Result(String, String) {
let url = \"https://jsonplaceholder.typicode.com/users/\" <> int.to_string(user_id)
case request.to(url) {
Error(_) -> Error(\"Invalid URL\")
Ok(req) -> case httpc.send(req) {
Error(_) -> Error(\"Network request failed\")
Ok(response) -> case response.status {
200 -> Ok(response.body)
_ -> Error(\"API returned status \" <> int.to_string(response.status))
}
}
}
}
Wait, that won't compile. Gleam doesn't have int.to_string
in scope. Imports are explicit - this trips people up.
I wasted 10 minutes staring at some error about "Unknown variable int
" thinking my installation was broken. Nope, just forgot the import:
import gleam/int // <-- Always forget this
Run It and Watch It Work
gleam run
If you get compile errors, read them. Gleam's error messages are actually helpful, unlike TypeScript's "Type 'string' is not assignable to type 'never'" nonsense.
Common first-project fuckups:
- Forgetting imports (add them)
- Typos in function names (Gleam catches these)
- Wrong types (the compiler tells you exactly what's wrong)
Editor Setup That Doesn't Suck
Install the VS Code Gleam extension. It actually works - real-time errors, go-to-definition, autocomplete that doesn't suggest random garbage.
I tried using vim with the Gleam plugin first because I'm stubborn. Spent two days fighting LSP configurations before giving up and switching to VS Code. Sometimes the easy path is the right path.
For Vim users who learn from my mistakes:
Plug 'gleam-lang/gleam.vim'
The Language Server Protocol support is solid. Unlike Python where the LSP suggests 47 different imports for json
, Gleam actually knows what types things are.