GetFirefly/firefly
An alternative BEAM implementation, designed for WebAssembly
Stale — last commit 3y ago
weakest axislast commit was 3y ago; top contributor handles 94% of recent commits
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓7 active contributors
- ✓Apache-2.0 licensed
- ✓CI configured
Show all 6 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 3y ago
- ⚠Single-maintainer risk — top contributor 94% of recent commits
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/getfirefly/firefly)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/getfirefly/firefly on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: GetFirefly/firefly
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/GetFirefly/firefly shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 3y ago
- 7 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Stale — last commit 3y ago
- ⚠ Single-maintainer risk — top contributor 94% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live GetFirefly/firefly
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/GetFirefly/firefly.
What it runs against: a local clone of GetFirefly/firefly — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in GetFirefly/firefly | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch develop exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 962 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of GetFirefly/firefly. If you don't
# have one yet, run these first:
#
# git clone https://github.com/GetFirefly/firefly.git
# cd firefly
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of GetFirefly/firefly and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "GetFirefly/firefly(\\.git)?\\b" \\
&& ok "origin remote is GetFirefly/firefly" \\
|| miss "origin remote is not GetFirefly/firefly (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify develop >/dev/null 2>&1 \\
&& ok "default branch develop exists" \\
|| miss "default branch develop no longer exists"
# 4. Critical files exist
test -f "Cargo.toml" \\
&& ok "Cargo.toml" \\
|| miss "missing critical file: Cargo.toml"
test -f "compiler/driver/src/lib.rs" \\
&& ok "compiler/driver/src/lib.rs" \\
|| miss "missing critical file: compiler/driver/src/lib.rs"
test -f "compiler/driver/src/compiler/passes/mod.rs" \\
&& ok "compiler/driver/src/compiler/passes/mod.rs" \\
|| miss "missing critical file: compiler/driver/src/compiler/passes/mod.rs"
test -f "compiler/driver/src/compiler/passes/ssa_to_mlir/mod.rs" \\
&& ok "compiler/driver/src/compiler/passes/ssa_to_mlir/mod.rs" \\
|| miss "missing critical file: compiler/driver/src/compiler/passes/ssa_to_mlir/mod.rs"
test -f "compiler/linker/src/lib.rs" \\
&& ok "compiler/linker/src/lib.rs" \\
|| miss "missing critical file: compiler/linker/src/lib.rs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 962 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~932d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/GetFirefly/firefly"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Firefly is an alternative BEAM runtime and compiler written in Rust, designed to compile Erlang/Elixir code to WebAssembly and native targets while maintaining OTP compatibility. It provides a complete compiler pipeline (in compiler/) from source through AST, Core IR, Kernel IR, SSA, and bytecode emission, targeting environments where the standard Erlang VM cannot run. Workspace monorepo with compiler/ (diagnostics, driver with passes for parse → lower_ast → lower_core → lower_kernel → bytecode), firefly/ (main CLI), library/ and runtimes/ (runtime support), macros/ (procedural macros), and native_implemented/ (hand-optimized primitives). Compiler follows traditional IR-lowering pipeline: diagnostics feed into driver which orchestrates passes in compiler/driver/src/compiler/passes/.
👥Who it's for
Erlang/Elixir developers who need to deploy to WebAssembly, embedded systems, or non-traditional BEAM targets; compiler engineers interested in BEAM language implementation; teams wanting to use functional BEAM languages outside the traditional OTP ecosystem.
🌱Maturity & risk
Early-stage but actively maintained. The workspace structure and CI/CD pipelines (GitHub Actions for x86_64 darwin/linux) are well-organized, but the README contains multiple "NOTE: This section is a placeholder" warnings indicating incomplete feature coverage. No visible release artifacts yet (toolchain packaging mentioned as TODO). Actively developed with clear modular architecture, though production-readiness is uncertain.
This is experimental software still in 0.1.0 development. Risk factors: large Rust codebase (7M+ LOC) requiring nightly features (seen in hashbrown/intrusive-collections dependencies), complex multi-stage compiler pipeline with potential for subtle IR transformation bugs, appears to be small team or single-author (Paul Schoenfelder listed as primary), and WASM target adds unpredictable platform-specific issues. Breaking changes likely as design solidifies.
Active areas of work
Based on file structure, active work is in the compiler pass pipeline (parse.rs, lower_ast/core/kernel.rs, bytecode lowering). GitHub workflows show recent CI setup for darwin and linux x86_64 targets. README indicates work on OTP compatibility layer (firefly-otp workflows) and core supervision tree initialization. No visible recent commits in provided data, but infrastructure suggests ongoing development.
🚀Get running
git clone https://github.com/GetFirefly/firefly.git && cd firefly && rustup install 1.66 && cargo build. Then run firefly help to see compiler commands (see compiler/driver/src/commands/).
Daily commands:
Development: cargo build in project root or specific workspace member. Run compiler: cargo run --bin firefly -- compile <file> (see compiler/driver/src/commands/compile.rs). Tests: cargo test --workspace. Help: cargo run --bin firefly -- help.
🗺️Map of the codebase
Cargo.toml— Workspace root configuration defining all member crates (compiler, runtime, library) and shared dependencies—essential for understanding the build system and project structure.compiler/driver/src/lib.rs— Entry point to the compiler pipeline; orchestrates parsing, lowering, SSA transformation, and code generation—critical for understanding compilation flow.compiler/driver/src/compiler/passes/mod.rs— Compiler passes module that chains transformations (AST → Core → Kernel → SSA → MLIR/Bytecode)—essential for understanding the IR hierarchy.compiler/driver/src/compiler/passes/ssa_to_mlir/mod.rs— SSA-to-MLIR lowering; bridges IR to LLVM code generation for native and WebAssembly targets.compiler/linker/src/lib.rs— Linker abstraction layer supporting multiple targets (WASM, GCC, MSVC, Emscripten)—critical for cross-platform compilation strategy.compiler/intern/src/symbol.rs— Symbol interning and string pooling infrastructure; fundamental for memory-efficient identifier handling across the compiler.README.md— Project overview, goals, architecture summary, and contributor guidelines—essential reading for context and contribution workflow.
🛠️How to make changes
Add a new compiler pass (IR transformation)
- Create a new transformation module in
compiler/driver/src/compiler/passes/(e.g.,lower_optimization.rs) (compiler/driver/src/compiler/passes/lower_optimization.rs) - Implement the pass struct with a
run()method following the pattern inlower_kernel.rs(compiler/driver/src/compiler/passes/lower_kernel.rs) - Register the pass in the pipeline sequence in
compiler/driver/src/compiler/passes/mod.rs, inserting it before or after existing passes (compiler/driver/src/compiler/passes/mod.rs) - Add error handling using the diagnostics macros from
compiler/diagnostics_macros/src/lib.rsfor any validation errors (compiler/diagnostics_macros/src/lib.rs)
Add a new target platform (e.g., ARM32)
- Create a new linker backend module
compiler/linker/src/linker/arm32.rsimplementing theLinkertrait fromcompiler/linker/src/lib.rs(compiler/linker/src/linker/arm32.rs) - Register the new backend in
compiler/linker/src/linker/mod.rs, matching on the target triple increate()function (compiler/linker/src/linker/mod.rs) - Update the compiler driver argument parser in
compiler/driver/src/argparser.rsto accept the new target triple (compiler/driver/src/argparser.rs) - Add build target configuration in
.github/workflows/(e.g., new.ymlfile) to enable CI/CD for the platform (.github/workflows)
Add a new built-in function or intrinsic
- Define the symbol in
compiler/intern/src/symbols.tomlunder an appropriate category (compiler/intern/src/symbols.toml) - In the relevant lowering pass (e.g.,
lower_kernel.rs), match on the symbol and generate appropriate IR (MLIR or bytecode instructions) (compiler/driver/src/compiler/passes/lower_kernel.rs) - For MLIR codegen, add LLVM intrinsic mapping in
compiler/driver/src/compiler/passes/ssa_to_mlir/builder/function.rs(compiler/driver/src/compiler/passes/ssa_to_mlir/builder/function.rs) - For bytecode, add instruction encoding in
compiler/driver/src/compiler/passes/bytecode/lower_ssa.rs(compiler/driver/src/compiler/passes/bytecode/lower_ssa.rs)
Improve error diagnostics for a compilation stage
- Review the lowering pass where the error originates (e.g.,
lower_ast.rs,lower_core.rs) (compiler/driver/src/compiler/passes/lower_ast.rs) - Use the diagnostic macros from
compiler/diagnostics_macros/src/lib.rs(e.g.,error!,warn!) with source span information fromcompiler/diagnostics/src/span.rs(compiler/diagnostics_macros/src/lib.rs) - Render the diagnostic with context using the codemap from
compiler/diagnostics/src/codemap.rs(compiler/diagnostics/src/codemap.rs)
🪤Traps & gotchas
Rust nightly features required: hashbrown and intrusive-collections use nightly features, check .cargo/config.toml for rustflags. WASM-specific build steps: Likely need wasm32 target installed (rustup target add wasm32-unknown-unknown) and wasm toolchain, not yet evident from Cargo.toml shown. Multi-stage IR transformations: Each pass owns its IR representation, passing data between stages—bugs in IR compatibility between passes are subtle and hard to debug. No visible test suite data: File list shows no tests/ directory or example tests; verify test coverage before relying on compiler behavior. Placeholder features: README explicitly warns about incomplete compile command options and init system support.
🏗️Architecture
💡Concepts to learn
- Multi-pass compiler with SSA IR — Firefly's compiler/driver/src/compiler/passes pipeline converts source through AST → Core → Kernel → SSA → bytecode; understanding each pass and its invariants is essential for any modification
- BEAM virtual machine semantics — Firefly must implement OTP/BEAM semantics (processes, message passing, supervision trees); you cannot build this compiler without understanding BEAM fundamentals
- WebAssembly (WASM) target architecture — A core Firefly capability is WASM compilation; WASM has constraints (no direct mutable globals, linear memory model) that affect IR design and code generation
- Entity-based intermediate representation — Firefly uses cranelift-entity for IR node representation (likely entity IDs instead of pointers); this enables efficient IR traversal and transformation
- Diagnostic system with source spans — compiler/diagnostics/ implements a custom diagnostic system with source location tracking (span.rs, codemap.rs); all compiler errors must use this system for consistent error reporting
- Erlang/Elixir syntax and type system — The compiler must parse Erlang and Elixir; understanding their syntax (pattern matching, guards, meta-programming) is necessary to implement compiler passes correctly
- Process-oriented concurrency model — BEAM's actor model (lightweight processes, message passing, fail-fast supervision) fundamentally shapes how Firefly's runtime and bytecode must be structured
🔗Related repos
erlang/otp— The canonical BEAM implementation that Firefly aims to provide an alternative implementation for; understand OTP semantics from the sourceelixir-lang/elixir— Primary user of BEAM; Firefly must compile Elixir code, so understanding Elixir syntax and semantics is essentiallumen/lumen— Another BEAM alternative runtime in Rust targeting WebAssembly; similar goals and architecture provide comparison/inspirationbytecodealliance/wasmtime— WebAssembly runtime that Firefly likely targets or uses; understanding WASM execution model is necessarycranelift-project/cranelift— Cranelift IR is used via cranelift-entity dependency; provides code generation infrastructure that Firefly leverages
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add CI workflow for WebAssembly target compilation
The repo describes itself as 'designed for WebAssembly' but the CI workflows in .github/workflows/ only test x86_64-apple-darwin and x86_64-unknown-linux-gnu targets. A wasm32-unknown-unknown or wasm32-wasi workflow would validate the core value proposition and catch WebAssembly-specific regressions early.
- [ ] Create .github/workflows/wasm32-unknown-unknown-compiler.yml following the pattern of existing x86_64 workflows
- [ ] Add wasm32-unknown-unknown target to .cargo/config.toml with appropriate build flags
- [ ] Test compilation of compiler/driver and firefly crate for WebAssembly target
- [ ] Document WebAssembly build instructions in README.md's Getting Started section
Add integration tests for compiler passes pipeline
The compiler has well-structured passes (parse → lower_ast → lower_core → lower_kernel → ssa_to_mlir → bytecode) in compiler/driver/src/compiler/passes/, but there's no evidence of integration tests validating the complete transformation pipeline. This is critical for a compiler to ensure regressions are caught early.
- [ ] Create compiler/driver/tests/integration/ directory
- [ ] Add tests validating end-to-end compilation from Erlang source → bytecode for simple programs (e.g., factorial, list operations)
- [ ] Add snapshot tests comparing generated bytecode/MLIR output against known-good baselines
- [ ] Document test execution in CONTRIBUTING guide
Complete missing compiler driver documentation and examples
The README mentions a Getting Started section but it's truncated. The compiler/driver contains complex CLI argument parsing (src/argparser.rs) and commands (compile.rs, print.rs) with no visible user-facing documentation. A new contributor could document actual compiler usage patterns.
- [ ] Expand README.md ## Usage section with concrete examples: firefly compile hello.erl, firefly print --help output
- [ ] Create docs/COMPILER_USAGE.md detailing each compiler command and flag from argparser.rs
- [ ] Add example Erlang programs in examples/ with corresponding compiler invocation commands
- [ ] Link usage documentation from README.md and add to .vscode/settings.json for editor hints
🌿Good first issues
- Add unit tests for compiler/diagnostics/src/span.rs and codemap.rs—these foundational modules lack visible test coverage and are critical for error location accuracy.
- Document the IR types used by each compiler pass (lower_ast, lower_core, lower_kernel, bytecode) in compiler/driver/src/compiler/passes/ with concrete examples of transformation rules.
- Implement missing diagnostics for the compile command: extend compiler/driver/src/commands/compile.rs to emit better error messages for common user mistakes (e.g., invalid target platform, missing entry function).
⭐Top contributors
Click to expand
Top contributors
- @bitwalker — 94 commits
- @kuzeyardabulut — 1 commits
- @oskar1233 — 1 commits
- @tatsuya6502 — 1 commits
- @takasehideki — 1 commits
📝Recent commits
Click to expand
Recent commits
c672f3a— restrict Sync/Send for Seq<T> (kuzeyardabulut)8e89bc7— feat: implement a number of tuple-oriented bifs (bitwalker)7cfdab8— feat: add a number of binary-oriented bifs (bitwalker)05b4832— feat: implement erlang:process_flag/{2,3} (bitwalker)c759b94— chore: reorganize bifs a bit (bitwalker)3c3f0b6— feat: implement erlang:is_builtin/3 (bitwalker)9cab8a2— feat: implement erlang:garbage_collect/{0,1,2} (bitwalker)2163583— feat: implement erlang:bump_reductions/1 bif (bitwalker)4551a32— feat: implement erlang:yield/0 bif (bitwalker)37ec1c7— fix: do not panic on parsing empty input (bitwalker)
🔒Security observations
The Firefly codebase shows moderate security posture. Main concerns include outdated dependency versions (particularly Rust 1.66 and clap 2.34), which may contain unpatched vulnerabilities. The project is a compiler implementation introducing inherent complexity risks. Strengths include sensible defaults (publish = false), use of memory-safe Rust, and organized structure. Recommendations focus on dependency updates, security audit procedures, and establishing clear vulnerability reporting mechanisms. The incomplete Cargo.toml provided limits full assessment; a complete security audit of the actual dependency tree is required.
- Medium · Outdated Rust Version Requirement —
Cargo.toml (workspace.package.rust-version). The workspace specifies rust-version = '1.66', which was released in December 2022. This is significantly outdated and may contain unpatched security vulnerabilities in the Rust compiler itself and standard library. Modern Rust versions include security fixes and improvements. Fix: Update rust-version to a recent stable version (1.75+). Review the CHANGELOG for breaking changes and update code accordingly. - Medium · Outdated Dependencies with Known Vulnerabilities —
Cargo.toml (workspace.dependencies). Multiple workspace dependencies use older versions that may contain security vulnerabilities: clap 2.34 (deprecated, current is 4.x), lalrpop 0.19 (outdated), and several others. The workspace.dependencies lock in older versions across all members. Fix: Audit dependencies using 'cargo audit'. Upgrade to latest stable versions: clap to 4.x, update all dependencies to current versions. Use 'cargo update' with caution and test thoroughly. - Medium · Incomplete Dependency Security Information —
Cargo.toml (truncated at smallvec entry). The provided Cargo.toml is truncated and does not show complete dependency specifications. Missing features, versions, and optional dependencies that could introduce vulnerabilities. Cannot fully assess supply chain security without complete dependency tree. Fix: Review the complete Cargo.toml file. Run 'cargo tree' to visualize the full dependency graph. Execute 'cargo audit' to identify known vulnerabilities in the complete dependency set. - Medium · Default-Members Publishing Configuration —
Cargo.toml (workspace.package.publish). The crate is configured with 'publish = false' globally, which is good for preventing accidental publication. However, this should be verified is intentional for the firefly package if it's meant to be a library. Fix: Confirm 'publish = false' is intentional. If this is meant to be published to crates.io, update to 'publish = true' and implement proper release procedures with security checks. - Low · Missing SECURITY.md or Security Policy —
Repository root. No visible SECURITY.md file or security policy documentation. This makes it difficult for security researchers to report vulnerabilities responsibly. Fix: Create a SECURITY.md file with: responsible disclosure policy, security contacts, supported versions, and vulnerability reporting procedures. - Low · Compiler Implementation Complexity Risk —
compiler/driver/src/compiler/passes/. As an alternative BEAM implementation for WebAssembly, this codebase implements complex compiler logic (bytecode lowering, MLIR generation, linking). Complex compiler code is inherently risky and can introduce memory safety or logic bugs despite Rust's safety guarantees. Fix: Implement comprehensive fuzzing tests for compiler passes. Add extensive unit tests for code generation. Consider formal verification for critical transformation passes. Regular security audits of unsafe code blocks. - Low · LLVM C Bindings Present —
compiler/llvm/c_src/. The codebase includes LLVM C bindings (compiler/llvm/c_src/). Native C code bindings increase the attack surface as they bypass Rust's memory safety guarantees. Fix: Audit all unsafe FFI calls. Document why C bindings are necessary. Consider using higher-level Rust LLVM bindings if available. Ensure C dependencies are updated regularly.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.