dot_claude/skills/gleam-expert/SKILL.md
Use when needing idiomatic, high-performance Gleam (v1.x) guidance for type-safe functional programming on Erlang or JavaScript targets.
npx skillsauth add nijaru/dotfiles gleam-expertInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
type. Model the domain; let the compiler enforce it.|> passes to the first argument (same as Elixir). To pipe to a different position, use a capture with _ as the slot: string.append("prefix", _) or an anonymous function.use for Result chains. Desugar callbacks; don't nest case pyramids.case expressions inside the body.:atoms — use custom type variants (PascalCase constructors) instead.Int and Float arithmetic — float operators are +. -. *. /.; no implicit coercion.Option/Some/None are in scope — they require import gleam/option.{type Option, Some, None}.panic/todo/let assert for recoverable errors — reserve them for programmer errors and impossible states.#{} — use <> for concatenation or string.concat/string.join.gleam_otp is Erlang-only.pub opaque type for domain types where constructors should be private. The only encapsulation mechanism.case: The compiler enforces it. Use guards (if) and alternative patterns (a | b) to stay DRY."https://" <> rest), list spread ([head, ..tail]), tuple (#(a, b)), field shorthand (name: binds to name).let assert for infallible patterns that should panic if violated — the compiler warns if it's provably redundant.Result(ok, error) everywhere. Chain with use:
use user <- result.try(fetch_user(id))
use token <- result.try(generate_token(user))
Ok(token)
result.try (flatMap), result.map, result.map_error, result.unwrap, result.all.Option bridge: option.from_result, option.to_result.fn greet(name name: String).list.map(items, int.add(_, 1)).src/ with / separators.gleam_otp + gleam_erlang packages.actor.new(state) |> actor.on_message(handler) |> actor.start.actor.continue(new_state) or actor.stop(reason).Subject(Msg) over raw Pid — typed mailbox reference.static_supervisor for fixed children, factory_supervisor for dynamic.@target(erlang) / @target(javascript) attributes..mjs path + exported function name. Erlang FFI: module atom + function atom."Elixir.ModuleName" atom prefix in FFI.gleam.toml: [javascript] typescript_declarations = true.snake_case — variables, functions, modules, fields.PascalCase for type names and variant constructors only.is_ prefix: is_empty, is_some, is_none (no ? suffix — that's Elixir).gleam format before committing.| Task | Command |
| :------------- | :------------------------------------------ |
| New project | gleam new |
| Build | gleam build [--target erlang\|javascript] |
| Run | gleam run [--runtime nodejs\|deno\|bun] |
| Test | gleam test |
| Format | gleam format |
| Add package | gleam add <package> |
| Check outdated | gleam deps outdated |
| Publish | gleam publish |
gleeunit. Test functions must end with _test. Use should.equal, should.be_ok, should.be_error.io.debug(value) prints any value and returns it unchanged — safe to insert mid-pipeline.gleam run with a scratch main.manifest.toml.development
Use after completing a bug fix, feature, refactor, or tk task when the first implementation taught enough context to replace it with a simpler, cleaner, or more coherent version before finalizing.
development
Use when writing, migrating, or reviewing Zig code across recent stable versions (0.14-0.16), especially to correct stale syntax or stdlib, build.zig, allocator, formatting, or runtime API knowledge.
documentation
Use when reviewing or revising text (prose, docs, commits) to remove AI patterns and improve voice/clarity.
content-media
Use when fetching X/Twitter post content by URL, or searching for recent X posts.