Superset of Haxe 4.3 MPL-2.0 In development

One language.
Every platform.
Continued.

A strict superset of Haxe 4.3, built on hxc, a faithful Haxe compiler written in Haxe. Every valid Haxe program compiles unchanged, and keeping it that way is the project's first commitment. On that foundation: the language features the community has asked for, a modern toolchain, and a compiler built so that adding platforms is cheap.

One hx+ source compiling to JavaScript, C++, Rust, C#, JVM, WebAssembly, Python, Lua, PHP, SPIR-V shaders, cppia and eval JavaScript C++ Rust C# JVM Wasm Python Lua PHP SPIR-V cppia eval
4M+downloads of the frameworks we maintain, #1 and #2 on haxelib
18parity gates against the reference compiler, from its unit suite to hxc's own source
0breaking changes, by design
30+features proposed for the RFC pipeline

01Compatibility

Your code already works here

hx+ isn't a fork. It contains Haxe 4.3, checked against the reference compiler with Haxe's own test suites. Our compatibility rules:

A stable std, guaranteed

For code on the 4.3 edition, existing standard-library APIs are not changed and not removed. New designs are built alongside, in new namespaces. Deprecation is a warning, never a break. Newer editions can change defaults or drop deprecated APIs, but only for modules that opt in.

Contextual keywords only

No identifier that is legal today stops being legal. New syntax arrives without reserving a single word your code might already use.

Editions for the long term

Long-term evolution happens through per-module editions, in the pattern Rust proved. Code written against the 4.3 edition keeps compiling, in the same build as new code.

02Architecture

Why a new compiler

What makes Haxe worth using is how far one codebase reaches: web, native, mobile and server. Keeping that going takes a compiler built for it.

Written in Haxe

The compiler is implemented in the language its community writes every day. If you write Haxe, you can read, debug, and improve your own compiler. Rust, Go, C# and Kotlin all made the same move.

Checked against the real compiler

hxc is tested against the reference Haxe 4.3 compiler with Haxe's own test suites, and the output is compared byte for byte. A target counts as conformant when it passes the same suite.

Cheaper targets

Every hxc generator is ordinary Haxe code. Next, every target moves behind one interface: a package of Haxe source compiled into hxc, with what it can do, its own filter passes, its generator and its build step. The built-in targets will use the same interface, so the people who need a platform can maintain it themselves, and the conformance suite tells them when it's right.

More targets, less risk

Haxe runs on other people's runtimes, so when a platform dies, code that can only run there dies with it. Haxe outlived Flash because the same code could move to other targets. Every target is one more place to land.

03The compiler

hxc: the compiler underneath

Underneath hx+ sits hxc, a faithful Haxe 4.3 compiler, written in Haxe and checked against the reference compiler with Haxe's own test suites.

Most serious languages end up compiling themselves

  1. Cfrom assemblyself-hosted since the 1970s
  2. Rustfrom OCamlrustc, self-compiling since 2011
  3. Gofrom Centirely Go as of 1.5
  4. C#from C++Roslyn, C# in C#
  5. Kotlinfrom Javacompiler written in Kotlin
  6. Haxefrom OCamlhxc

Rust's first compiler was written in OCaml and was replaced once Rust could compile itself. TypeScript went the other way: Microsoft moved its compiler to Go for speed, because TypeScript compiles to JavaScript. Haxe compiles to native code, so hxc is self-hosted and still a native binary.

  • Self-hosted. The compiler is written in Haxe, so if you write Haxe you can read, debug and fix your own compiler in the editor you already use.
  • Checked, not trusted. Haxe's unit suite at zero failures, with output and compiler messages compared byte for byte against the reference compiler.
  • Native. Built with hxcpp into a native binary, so being written in Haxe doesn't cost speed.
  • Built to be extended. Every generator is ordinary Haxe code, and targets are moving behind one interface, so the typer and optimizer will ask a target what it can do instead of which target it is.
terminal
# install it from haxelib
$ haxelib install hxc
# then use it wherever you would run haxe
$ haxelib run hxc build.hxml

Same command line, same hxml.

04In the browser

The compiler, in a browser tab

Because hxc is ordinary Haxe, it compiles to WebAssembly like any other Haxe program. The result runs entirely client-side: write Haxe, compile it, run it, and share it by link, with no build server and nothing to install. OpenFL projects compile and render the same way.

That's haxe.run, the playground every hx+ proposal will ship with, so the community can argue about a feature by running it.

05The language

What hx+ adds

First, the features Haxe developers have requested for years. Then a public RFC pipeline, where every proposal ships with a live playground so the community debates by trying, not imagining.

Save.hxhx+
// Real constants, evaluated at compile time
const TAU = 2 * Math.PI;

// try / catch / finally, at last
function save(state:GameState) {
    var file = File.write(SAVE_PATH);
    try {
        file.writeString(state.serialize());
    } catch (e:IoError) {
        Log.warn('Save failed: ${e.message}');
    } finally {
        file.close();
    }
}

try / catch / finally

Requested for over a decade. Implemented directly in the compiler, lowered per target to native finally where the platform has one.

const: real constants

Initializers evaluated at compile time and spliced as literals, powered by the compiler's own eval engine. A guarantee final never gave you.

Records & structural equality

Declarations with derived equality, hashing, and copying, generated at compile time. The end of hand-rolled deep-equals in every project.

Modern networking

A clean-sheet, dual-stack networking package: IPv6 at last, TLS and WebSockets as part of it, and an HTTP client and server. The legacy API stays working.

Coroutines, absorbed

Structured async on the Haxe 4.3 base, on our own schedule: modern ergonomics and the full target matrix, without choosing between them.

Compile-time toolkit

nameof, static assert, and compile-time file embedding, powered by the eval engine the compiler already carries.

Proposed for the RFC pipeline

Syntax
tuples & multi-return destructuring using & defer cascade operator .. let-else bindings pipe operator |> safe cast as? opaque typedefs property shorthand enum methods range slicing & membership raw string literals tagged templates digit separators binary literals
Compile time
records & structural equality method contracts static assert nameof compile-time embed compile-time evaluation
Standard library
WebSockets & TLS modern crypto modern date & time sized numerics u8..i64, f32 Unicode utilities BigInteger std test runner
Type system & editions
strict null safety named & named-only arguments union types with narrowing async / await on coroutines overloading for classes smart casts

Nearly every item here traces to a longstanding request in the Haxe issue tracker, some open for a decade: this is largely the community's own wishlist, aged in public. The deeper type-system work, shown dashed, arrives through editions where it must.

06Platforms

Targets

Tier 1 targets are maintained by the core team and release-gated on full conformance. Tier 2 targets are community-maintained through the Target SDK, measured by the same public suite. A community target that keeps passing can move up a tier. The targets marked considering are the kind the SDK is meant to let communities own.

Tier 1core maintained

  • JavaScript
  • C++ hxcpp
  • eval macros
  • cppia
  • JVM bytecode

Comingin order of need

  • Rust in progress
  • C# modern .NET
  • Java modern JVM
  • WebAssembly WasmGC
  • PHP
  • Python
  • Lua

ConsideringSDK-shaped

  • Kotlin
  • TypeScript emission
  • Go
  • Swift

Tier 2: any community target that sustains conformance through the SDK.

Tiers can change

A Tier 2 target whose community keeps it conformant can move up. HashLink bytecode and Flash are Tier 2: welcome, but not promised.

Retiring Neko

Neko is a custom runtime the ecosystem maintains by hand, no products ship on it, and eval, cppia and HashLink cover what it does. We'll retire a target nobody depends on, never one people rely on.

How targets will plug in

The pipeline stays fixed. The target fills its slots.

We're moving hxc's targets behind one interface, starting with C++. Once they're there, the typer, filters and optimizer stop testing which target is selected and read what it declared it can do instead. Everything target-specific arrives through three kinds of contribution, and the built-in targets use exactly the same interface as anyone else's.

  1. configuretarget
  2. parse & typecore
  3. filters+ target passes
  4. analyzercore
  5. filters+ target passes
  6. generatetarget
  7. buildtarget

Capabilities

Plain data, resolved once before typing: overloads, null padding, capture policy, analyzer and optimizer rules. Read in the hot paths as fields, so a plugged-in target compiles as fast as a built-in one.

Passes

Filters the target places at named slots in the compiler's pipeline, before or after a named pass. The order itself never changes.

Stages

Whole-program calls: configure, generate, and build, where the target chooses its own runtime and toolchain.

A second C++ backend, beside the first

C++ moves behind the interface first, so a second C++ backend can grow next to the original instead of replacing it in place. It starts byte-identical, diverges on purpose with the original as its live reference, and pairs with a runtime of its own, which makes changes that need both sides possible, such as precise GC roots. It reports itself as C++, so #if cpp code in Lime, OpenFL and native extensions compiles unchanged.

A different kind of target

Shaders, in the same language and the same types

Graphics code is the daily work of much of this ecosystem, written today in a separate language, with separate types, checked by nothing until it fails at runtime. A shader target compiles a restricted subset of hx+ to SPIR-V, with WGSL, GLSL, and HLSL alongside.

What makes it useful is that both sides use the same types, so uniforms, vertex attributes and buffer layouts are checked by the compiler instead of turning up as a black screen.

Wave.hxSPIR-V
// one declaration, both sides of the boundary
@:uniform var time:Float;
@:uniform var tint:Vec4;

@:shader(fragment)
function main(uv:Vec2):Vec4 {
    var wave = sin(uv.x * 12 + time) * 0.5;
    return tint * (0.5 + wave);
}

One language, every engine

Most Haxe code that reaches consumers ships inside a game engine. The community proved the demand and the technique; these deserve a toolchain that treats them as first-class.

Unreal Engine

Building on the hxcpp path unreal.hx proved in commercial production: Haxe classes as UCLASS citizens, Blueprint interop, full engine API access.

Godot

The GDExtension route via hxcpp, as HxGodot demonstrates, with the Rust target as a second integration avenue as it matures.

Unity

Riding the new C# target: Haxe compiling to idiomatic, modern C# that Unity consumes natively.

07Developer experience

The toolchain is the language

What pushes teams away from Haxe usually isn't syntax. It's tooling.

Real dependency management

Per-project, lockfile-based, reproducible builds with content hashes. Vendoring for studio CI. A registry with target and edition compatibility metadata, and a bridge so existing haxelib packages keep working from day one.

Diagnostics as a product

Error messages with explanations, suggestions, and documented error codes. The same structured output that helps you repair code is what makes AI-assisted development precise.

The live loop

An official REPL, powered by the compiler's own eval engine. Watch-mode builds and hot-reloadable scripting. The tight development loop as a toolchain feature, not an accident.

Editions for the long run

Strict null safety by default, delivered as an edition your project adopts module by module. The language moves; nobody's code is left behind.

hxia: Haxe Intermediate Assembly

A scripting layer for shipped applications: one artifact that loads into the native build and the web build of the same program. The runtime is Haxe compiled into the host, so script values are host values, with no marshalling boundary and no second heap. Untrusted content runs on a metered, capability-gated tier; trusted content takes the fastest engine each host already has. Modding, plugins, and live content, portably.

08The plan

Roadmap

Where things stand, honestly. This work did not begin recently: the earliest prototypes date to the Haxe 3 era. Today hxc 0.6.6 is on haxelib. It compiles real projects and passes an 18-gate parity battery against the reference 4.3 compiler: Haxe's unit suite with JavaScript and C++ output byte-identical across the dead-code and analyzer settings, Haxe's sys and threads suites under its interpreter, every hxcpp test suite, the warm compilation server, and a rebuild of its own source. It builds Lime and OpenFL applications, and compiled to WebAssembly it runs in the browser, which is what the haxe.run playground is built on. hxia runs: one mod, compiled once, loads into the C++ and JavaScript builds of the same game and plays identically. hxc also generates JVM bytecode, and the experimental Rust backend runs. The hx+ language features and the modern networking package are designed and specified but not yet shipped. They land in the order below, and nothing here should be read as claiming otherwise.

Phases are ordered by what depends on what, and every phase ships something usable on its own.

  1. Battery green

    Phase 1: Parity

    Haxe's own suites at parity with the reference 4.3 compiler: eval and macros, then JavaScript, then C++ and cppia. The final gate: Lime and OpenFL build and run, unmodified.

  2. Underway

    Phase 2: In the browser

    The compiler running client-side at haxe.run: write, compile, run, share. Community spaces go public alongside the playground.

  3. Next

    Phase 3: hx+ 1.0

    Editions, finally, const, the transpile-to-Haxe mode, and the Target SDK on the target interface, which C++ moves behind first. The Rust backend ships as a preview. The first RFCs open with the release.

  4. Planned

    Phase 4: The platform

    Modern networking (IPv6, TLS, HTTP, WebSockets), the package manager with its haxelib bridge, and the official REPL. Pipeline features begin landing on a steady cadence.

  5. Planned

    Phase 5: Widening the matrix

    Rust to full conformance. Clean-sheet C# and Java. WebAssembly on WasmGC. PHP, Python, and Lua carried forward as their conformance suites go green.

  6. Planned

    Phase 6: Engines

    First-class integration for Unreal Engine, Godot, and Unity: gameplay code written once, moving between engines the way Haxe already moves between platforms.

09The document

Read the whitepaper

The full case: why we built it, the compiler, the compatibility rules, licensing and the plan.

An invitation

01

Try it

Bring your existing code; it should simply compile. When it doesn't, that's a bug against a promise, and we want the report.

02

Argue with it

The first RFCs open with the first release. If a feature is wrong, say so with a playground link showing why. That is how this language will be governed.

03

Build a target

If there's a platform you need and the ecosystem lacks, the Target SDK and its conformance suite are there for that. You don't need anyone's permission.

Haxe's original idea, one language for every platform, is worth keeping, and we built the tools to keep it.

10Questions

FAQ

Is this a fork of Haxe?

No. hx+ contains Haxe 4.3. Your code compiles unchanged, and keeping it that way is the project's first commitment. hxc is a faithful Haxe 4.3 compiler, and hx+ is a strict superset on top of it.

Why not just contribute to the official compiler?

The problem isn't a shortage of hands; it's structural. An OCaml codebase limits contributors to people who know both worlds well. hxc changes the structure instead. Nothing is held back: everything we build is open, and MPL code can go into GPL projects, so upstream can take any of it.

What stops hx+ from meeting the same fate it responds to?

Incentives and design. The people maintaining this toolchain ship the ecosystem's most used frameworks on it, so keeping it healthy isn't optional for us. It also doesn't depend on a small group's attention: the compiler is written in the language its users already know, correctness is checked by test suites instead of living in a few people's heads, and targets are owned by the communities that need them.

Will my existing code or libraries break?

No. That is the one promise this entire project is architected around. Existing std APIs are stable and stay in place, new syntax is contextual-keyword only, divergence is opt-in, and the narrow exceptions (security fixes, platform withdrawals) are published in advance.

Will my editor and build setup keep working?

Yes. The compiler presents the same CLI and hxml interface, works with existing haxelib workflows, and speaks the same display and diagnostics protocol that powers today's IDE plugins.

How do I try hxc?

Install it from haxelib with haxelib install hxc, then run haxelib run hxc build.hxml wherever you would run haxe. The package includes the compiler for Windows x64; on other platforms, build it from source (see GitHub). Or try it with nothing installed at haxe.run.

How would I add a target?

Write it as a package of Haxe source: the capabilities it declares, any filter passes it needs, a generator and a build step. Put it on the class path and rebuild hxc with hxc. The built-in targets are written the same way, and you test yours with the same conformance gate that brought hxc to parity.

Why base on Haxe 4.3 rather than tracking Haxe 5?

Haxe 4.3 is the last release line with the full target matrix, and the target matrix is the point. The language evolves independently on that base, with its own release cadence, and absorbs individual improvements from any source when they serve the goal.

Who controls hx+?

An open RFC process, in public, with working playground demos attached to every proposal. The compatibility guarantees are standing commitments, not preferences.

What license?

Mozilla Public License 2.0 wherever the code is ours to license. File-level copyleft keeps compiler improvements open; applications and engines that embed the toolchain take on no obligations for their own code.