npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

gelang

v0.1.7

Published

One typed source language, compiled to Rust, C++, C#, Zig, Go, or Kotlin — chosen per function. Generates Flutter and React UIs from one DSL.

Readme

GE

A typed, multi-target systems language. Write Python-like or TypeScript-like source, compile to native Rust, C++, C#, Zig, Go, or Kotlin — with the backend chosen per function.

npm CI License: MIT Python 3.10+

GE is a compiler. You write .ge files in Python-flavoured or TypeScript-flavoured syntax — or both in the same file — and GE emits native code for the backend that suits each function, then links everything into a single executable.

npx gelang doctor                          # check what you have
npx gelang build main.ge --run             # compile and run
"""main.ge — Python flavour and TypeScript flavour in one file."""

<factorial:typescript>
export function factorial(n: number): number {
    if (n <= 1) {
        return 1;
    }
    let result: number = 1;
    let i: number = 2;
    while (i <= n) {
        result = result * i;
        i = i + 1;
    }
    return result;
}
</factorial>

<greet>
def greet(n: int) -> int:
    return n * 7
</greet>


def main() -> None:
    print(@factorial(5))     # 120
    print(@greet(6))         # 42
$ ge build main.ge --run
120
42

Contents


Why GE

Compiled, not interpreted. Other polyglot tools dispatch to language runtimes. GE lowers every flavour to one typed IR and emits native code from it, so the result is a single binary with no interpreter in the loop.

The backend is chosen per function, not per project. A hot arithmetic loop and a UI renderer have different needs. GE scores each function and picks, or you pin one explicitly with @rust, @cpp, @csharp, @zig, @go, or @kotlin.

Mixed backends link into one binary. A Rust shell over a C++ renderer compiles to a single executable — no shared library, no IPC, no runtime FFI marshalling. ge build derives the extern "C" declarations on both sides from the call graph.

Small binaries. A desktop application with a native window, audio capture, and HTTPS is roughly 15 MB. The same application on Electron is 120–200 MB.

Two UI ecosystems from one DSL. .ge.ui generates either Flutter/Dart or React 19 + TypeScript + Vite. Generated files are yours to edit; regeneration never overwrites them unless you pass --force.

Verifiable by design. ge diff runs a program through CPython and every installed backend, comparing output byte for byte. ge golden pins emitted code so it cannot drift. ge api-check guards the CLI surface. All three run in CI.

Suited to AI-assisted development. GE's input syntax is Python and TypeScript, so existing model knowledge transfers directly. Named blocks give an assistant a bounded unit with an explicit call contract, and the compiler rejects an invalid signature at build time rather than at runtime.


Install

npm (recommended)

npx gelang doctor            # one-off, no install
npm install -g gelang        # or install globally

The npm package bundles the compiler source and runs it with your system Python. No pip install, no network access at install time.

pip

pip install gelang
ge doctor

From source

git clone https://github.com/Zrald1/gelang.git
cd gelang
pip install -e .
ge doctor

Requirements

GE itself needs Python 3.10+. To compile, you need at least one native toolchain. Each one you add widens the set of targets.

| Backend | Toolchain | Install | |---|---|---| | Rust | rustc ≥ 1.70 | winget install Rustlang.Rustup · brew install rustup-init · rustup.rs | | C++ | clang++ or g++ ≥ 10 | winget install LLVM.LLVM · brew install llvm · apt install clang | | C# | .NET SDK ≥ 8 | winget install Microsoft.DotNet.SDK.8 · brew install --cask dotnet-sdk | | Zig | zig ≥ 0.13 | ziglang.org/download · brew install zig | | Go | go ≥ 1.21 | winget install GoLang.Go · brew install go · apt install golang | | Kotlin | kotlinc-native ≥ 2.0 | Kotlin releases |

Optional, for UI targets:

| Target | Toolchain | Command | |---|---|---| | Flutter / Dart | Flutter SDK | ge flutter | | React + TypeScript | Node.js + npm | ge react |

Run ge doctor any time to see what is detected and what is missing.


Quick start

# 1. check your environment
npx gelang doctor

# 2. scaffold a project
npx gelang create myapp --template desktop-gui -y
cd myapp

# 3. build and run
npx gelang build desktop/main.ge --run

Two templates ship today:

| Template | What you get | |---|---| | desktop-gui | Rust shell + C++ core + C++ UI (native Win32 window) | | web-react | React 19 + TypeScript SPA + Rust backend |

ge create myapp --template desktop-gui -y
ge create myapp --template web-react -y

The language

Flavours

| File | Frontend | Notes | |---|---|---| | foo.ge | hybrid | Canonical. Flavour detected per chunk. | | foo.ge.py | python | Whole file is Python-flavoured | | foo.ge.ts | typescript | Whole file is TypeScript-flavoured |

A single .ge file may mix both. The compiler classifies each top-level chunk from its syntax and lowers it.

Python flavour

from pyeffic.backends import cpp, rust


@rust
def checksum(data: list) -> int:
    total: int = 0
    for x in data:
        total = total + x
    return total


@cpp
def render(value: int) -> int:
    return value * 2

TypeScript flavour

export function factorial(n: number): number {
    if (n <= 1) {
        return 1;
    }
    let result: number = 1;
    let i: number = 2;
    while (i <= n) {
        result = result * i;
        i = i + 1;
    }
    return result;
}

Types map as number → int, string → str, boolean → bool, T[] → list, void → None. console.log becomes print, Math.floor becomes int, arr.length becomes len(arr).

A Python signature with a braced body

Both spellings are accepted:

def clamp(v: int) -> int:
    if (v > LIMIT) {
        return LIMIT;
    }
    return v;

Escape hatches

When you need to drop to the target language:

| Python flavour | TypeScript flavour | Scope | Purpose | |---|---|---|---| | ge_preamble(backend, code) | gePreamble(...) | module level | File-scope injection (includes, FFI, statics) | | ge_inline(backend, code) | geInline(...) | function body | Target-specific inline expression | | ge_raw(code) | geRaw(...) | function body | Unconditional raw code |


Named blocks

A block gives a chunk a name and makes it callable from anywhere in the file, regardless of which flavour either side uses.

<add>
def add(a: int, b: int) -> int:
    return a + b
</add>

<render:typescript>
export function render(x: number): number {
    return @add(x, 1);      // @block(...) calls the block
}
</render>

Rules:

  • <name> opens, </name> closes. Tags must match.

  • Language is detected from the content, or pinned with <name:python> / <name:typescript> (aliases :py / :ts).

  • @name(...) calls the block. It resolves to the function inside the block named name, or to the block's only function if the names differ.

  • A call site may appear before the block it names.

  • Backend decorators (@cpp, @rust, …) are never rewritten — @ident( is a call, bare @ident is a decorator.

  • @name( inside a string literal is left alone.

  • Pin an ambiguous chunk with a marker comment:

    # ge:typescript
    const SCALE: number = 2;

Backends

| Backend | Decorator | Emits | Runs as | |---|---|---|---| | Rust | @rust | build/<target>/backend/*.rs | native exe / cdylib | | C++ | @cpp | *.cpp | native exe / object / dll | | C# | @csharp | *.cs | NativeAOT exe / dll | | Zig | @zig | *.zig | native exe / shared lib | | Go | @go | *.go | native exe / c-shared lib | | Kotlin | @kotlin | *.kt | Kotlin/Native exe / lib |

Without a decorator, GE scores each function and picks. Explicit decorators always win.

Mixed-backend linking

When a program spans more than one native backend, ge build does the whole job itself:

  1. Emits each non-entry backend in library mode with extern "C" exports and compiles it to an object file.
  2. Emits the entry backend (Rust by default) with matching extern "C" declarations derived from the call graph.
  3. Links the objects into one executable.
ge build desktop/main.ge --run      # Rust shell + C++ core → one .exe

No build script and no hand-written FFI declarations are needed.


UI targets

Flutter / Dart

ge flutter app/main.ge --app-name myapp
cd build/mobile/myapp && flutter pub get && flutter run

React + TypeScript

ge react ui/main.ge.ui --app-name myapp
cd build/web/frontend && npm install && npm run dev

ge react reads a .ge.ui DSL file and generates a Vite project with one component per file. Existing files are kept unless you pass --force.

Window {
  title: "My App"
  Column {
    padding: 24
    children:
      Text "Hello" style="headline"
      TextField state="query" hint="type here"
      ElevatedButton "Run" on_click=Action(call="compute")
      Text state="result" style="value"
  }
}

CLI reference

ge doctor                     Check runtime + toolchains, with install hints
ge compilers                  Show detected toolchains
ge create [NAME]              Scaffold a project (--template, --platforms, --backends)
ge build <file>               Compile (--backend, --target, --run, -o)
ge analyze <file>             Type check and report diagnostics
ge diff <file-or-dir>         Prove every backend matches CPython byte-for-byte
ge golden --check             Prove emitted code has not drifted
ge api-check                  Prove the CLI surface has not changed
ge react <ui.ge.ui>           Generate a React + TypeScript UI
ge flutter <file>             Build a Flutter app (native FFI lib + Dart UI)
ge pack <file>                Bundle into a single .ge package
ge install <package>          Unpack and build for a target
ge deploy <package>           Distribute and run
ge tools list|install|check   Manage toolchains
ge bench                      Benchmark against hand-written C++

Common flags

| Flag | Meaning | |---|---| | --backend rust\|cpp\|csharp\|zig\|go\|kotlin\|auto | Force a backend (default auto) | | --target desktop\|web\|mobile\|crossplatform | Platform bucket | | --entry NAME | Entry point function (default main) | | -o, --out-dir DIR | Output root (default build) | | --run | Run after a successful build |


Project layout

Build output

build/
  desktop/          native build
    backend/          generated sources
    obj/              object files
    bin/              executables
  web/              web build
    backend/  obj/  bin/
  mobile/           Flutter project
    <app>/backend/    native FFI library
    <app>/ui/         generated Dart UI
    <app>/lib/        Dart bindings

A scaffolded project

myapp/
  app/
    memory/       bounded state (limits, buffers, slots)
    core/         computation, one function per file
    ui/           theme, layout, widgets, render
    main.ge       aggregator
  desktop/
    main.ge       entry point
  tests/
  ge.toml

Verification

GE ships the machinery to prove it is correct, not just that it runs.

# every backend must produce the same output as CPython
ge diff tests/differential

# emitted code must not drift, and must still behave
ge golden --check

# the CLI / diagnostics / intrinsics surface must not move
ge api-check

# the full suite
python -m unittest discover tests

| Guard | What it catches | |---|---| | ge diff | Backend-specific codegen bugs, semantic drift from Python | | ge golden | Silent emitter churn — code that still compiles but changed | | ge api-check | Renamed flags, removed commands, reused diagnostic codes | | Test suite | Everything else, including 600 compile-and-run cases |


Compatibility

GE is pre-1.0. The promise and the mechanisms behind it are documented in docs/COMPATIBILITY.md:

  • A released .ge program keeps compiling and keeps producing the same output, within its edition.
  • Breaking changes go into a new edition — never a patch or minor release.
  • Editions interoperate: a module on a newer edition is importable from an older one.
  • Deprecations last at least two minor releases with a published removal version.
  • Unstable features require explicit opt-in.

See also docs/STABILITY.md (how it works) and docs/PRODUCTION_GAPS.md (what is not done yet).


Requirements

| Component | Minimum | |---|---| | Python | 3.10 | | Node.js (npm install only) | 16 | | rustc | 1.70 | | clang++ / g++ | 10 | | .NET SDK | 8 | | zig | 0.13 | | go | 1.21 | | kotlinc-native | 2.0 |

GE detects whatever versions you have — no pinned toolchains, no version switching.


Troubleshooting

GE needs Python 3.10 or newer Install Python, or point GE at one with GE_PYTHON=/path/to/python.

0 of 6 native backends available You need at least one compiler. ge doctor prints the install command for your platform.

A build succeeds but nothing runs Some constructs fall back to CPython instead of native code. The build summary lists them under fallback:. See docs/PRODUCTION_GAPS.md §C4.

ge build says "renamed 'x' -> 'x_'" x is a reserved word in a target language (e.g. double is a C++ type). GE renames the symbol consistently on both sides of the ABI.

Generated React files were overwritten They are not, unless you pass --force. ge react only writes files that do not exist.


Contributing

See CONTRIBUTING.md. Two guides for extending GE:

  • Add a backend — pyeffic/emitters/<name>.py + a Spec + a compiler entry
  • Add a frontend — pyeffic/frontends/<name>.py + suffix registration

AGENTS.md documents the architecture in detail for AI coding agents.


License

MIT. See LICENSE.