A Python-shaped language for the BEAM.

Immutability, pattern matching, comprehensions and hierarchical modules — written in the Python you already know, compiled to Erlang abstract forms through the same pipeline Gleam uses.

Read the syntax overview →
def fib(n, current, next):
    match n:
        case 0:
            current

        case _ if n > 0:
            fib(n - 1, next, current + next)

def fib(n):
    fib(n, 0, 1)

compiled · one function with a match instead of Erlang's multiple clauses

Eel's objectives

Eel is inspired by Gleam, but its goals and founding principles differ in a few important ways.

01

Great IDE support

static analysis, first-class

A great static-analysis experience in the IDE is one of the goals — and the main target is PyCharm.

02

Great stdlib

batteries, with methods

A stdlib that is pleasant to use, with OOP-style methods on the core data structures.

03

Optional static typing

never mandatory

Static typing is fully optional. When you reach for it, it is there to make the code clearer and more expressive.

04

All data types equally supported

no second-class data

Maps, records, native records and the rest get the same level of support — and optional types make all of them convenient.

05

OTP first-class

not an afterthought

Working with OTP matters as much as a good standard library.

06

Python-friendly

BEAM ↔ CPython

One of the tasks is to bring the BEAM and CPython ecosystems closer, and to enable projects like Hornbeam.

Almost Python

Every construct below is compiled, not interpreted: the compiler turns this Python into Erlang abstract forms. Pick a category and read the code.

Numbers, floats, strings, atoms, booleans and None. Lists, tuples and dicts keep their Erlang shapes.

values.eel
def values():
    (42, 1.5, "hi", 'ok', True, False, None)

def collections():
    ([1, 2, 3], (1, 2), {'a': 1}, {"b": 2})

OOP-styled standard library

OOP-styling is a special feature of Eel: it makes the standard library pleasant to use, without complicating anything — outside the standard library, "OOP style" is not allowed.

Strings

  • name.startswith(prefix)prefix test, bytes included
  • name.strip()trim whitespace on both ends
  • line.split(sep)split into a list of strings
  • path.replace(from, to)replace every occurrence
  • sep.join(items)join a list back into one string

Maps

  • m.get(key)value or nil, never an exception
  • m.keys()keys, in no particular order
  • m.items()pairs, for comprehensions

Collections

  • li.map(f)apply a function to every element
  • li.filter(pred)keep the elements that match
  • zip(li1, li2)pairs, like Python's zip
  • enumerate(range(5))Python's enumerate

This is an early alpha.
100% vibe-coded.

It compiles real modules today, however it is not something you put in production yet. Also, the code was written mostly with DeepSeek 4 Flash, in a vibe-coding loop.

plus

  • A small codebase you can fork the compiler is a handful of Python modules: read it in an afternoon, fork it, and bend it to your own project.

minus

  • Everything else is a minus.