Is haxe alive or dead?

I knew I should have checked some of my assumptions but laziness got the best of me :smiley: … thank you for the clarifications!
I would make a small objection to the Xml syntax, since it requires annotation and it is not part of the language like JSX/TSX. Also I am not a super fan of annotating everything with @:something :wink:

Hmm, but it is, no? It is a first-class citizen, you just need to process it to add your semantics? hxx is great with inline markup, for example. JSX/TSX is not part of JS/TS’s specification, AFAIK?

My point is that custom`<magic/>` Is not the same as <magic/>. Yes JSX/TSX are not part of the official specifications and need to pass through special pre-processors but that is so mainstream that is really not an issue. I guess my main concern with the Haxe syntax is that it is hard to extend into the syntax highlight and the LSP (but maybe this is already a solved issue I am not aware of?).

1 Like

I would agree that the TypeScript DX is more stable, even though inferior. The amount of tricks added in vshaxe is impressive, but the moment you start using macros, it starts degrading and it’s hard to stay on top.

But I think it was never about DX in the first place. It’s easy to point at the places where it’s obviously annoying, but if you look at which languages are popular, DX is typically not a factor - to the contrary: once a language becomes popular enough, the community is big enough to put enough energy into DX.

TypeScript won so clearly over Haxe in web development for two reasons:

  1. One thing we could do something about, although I’m not sure it would move the needle: Haxe is built for games and typically just rejects everything outside that domain. On one side there is the open disdain for web development, that leads to sweeping rejection of anything that would be useful there, whether it’s good or not. On the other side is how poor the type system is when it comes to readonly/immutable types. Haxe has so much cool stuff taken from functional languages, but the way it deals with mutability makes it superbly awkward to have meaningful guarantees, at the best of times. Which traces back to the fact that Haxe is so deeply steeped in gamedev culture, where mutation is preferred over allocation, because some runtimes can’t handle it all too well.
  2. One thing that we have to accept as a given: Most web apps are barely working code put together by mediocre developers. To be clear: there’s nothing wrong with either. Clearly, there’s a market for those apps and clearly it doesn’t require skilled programmers to create those. But: Haxe is not particularly aimed at that use case or that crowd and it never will be. In fact it is the diametrical opposite. Most web devs just wanna play it safe. In one of my recent TypeScript projects, the amount of crap I got simply for choosing Preact over React (which is 98% the same thing, but a fraction of the size and much better runtime characteristics) is unimaginable to a thinking person.

Realistically, Haxe never really competed with TypeScript, simply because the audiences are so different. What I think is a bit of a missed opportunity is that Haxe failed to capture a large enough niche in webdev, like for example Gleam, that Franco mentioned. Haxe definitely has the potential for that and it’s truly heart breaking to not see that happen.

5 Likes

As the person currently developing the most comprehensive backend framework ever made for Haxe, I completely agree. I almost never use macros and try to keep them to an absolute minimum. While they don’t offer much of an advantage in web development, they do seem far more suited for game development.

Furthermore, building an HTTP server exposes severe limitations in the Haxe standard library, and there are virtually no native workarounds. Unless you’re targeting the JVM and leveraging Java’s Virtual Threads, you are essentially forced into a blocking ‘1 thread = 1 socket’ model. As you can imagine, this is not a production-ready solution by any means; it’s merely a stopgap.

2 Likes

Macros offer a massive advantage in web development. Suggesting otherwise is harmful to anyone who might come across this thread and act on such advice. But the risk is indeed that it negatively impacts DX and that’s something to contend with - not to outright avoid.

I cannot leave this unchallenged as is. People evaluating Haxe might read this and come to wrong conclusions. So: nobody forces you to do such a thing in Haxe. The standard approach is to use something like ThreadServer or to roll your own, or to simply target nodejs. Or if you’re targeting JVM, then you can build on top of Vert.x (or just Netty), Play (or just Akka/Pekko) or whatever, really.

I do agree that just trying to build a web server on scratch on top of the sys package can be unduly painful. Whether it’s a good approach depends very much on the use case. I would say that the solution the compiler team is working on to address this is the asys package that is currently under development.

2 Likes

I do not deny the advantages that macros offer in terms of compile-time safety and performance. However, as a framework architect, my priority is transparency and maintainability. Heavy macro use creates a ‘black box’ effect, making debugging difficult and steepening the learning curve. My approach is to keep macros as an ‘optimization’ that works behind the scenes, not a ‘must’; so the developer doesn’t have to be a compiler expert to understand how the framework works.

What I lose for these are contributors and potential users who don’t know how haxe macros work.

If instead want to target people who are not in the current ecosystem, minimizing macros will at least make them feel like they are developing a language they know.

Take an SQLBuilder as an example. Using macros to evaluate a compile-time expression and convert it directly into an SQL string absolutely removes runtime overhead. Yes, it is an optimization, but that overhead is already negligible. Chasing such a minor performance gain ultimately complicates the development process for both yourself and any potential contributors.

ThreadServer is unfortunately not a cross-platform solution.

Your only chance is to use the Socket API, as in Java, a “socket().getInputStream().available()” approach is not possible, unfortunately, it has to be Blocking.

Using nodejs is not a solution because it leaves you tied to a single target, which is against the spirit of haxe and is an async solution.

Coming to asys, it is an asynchronous socket type by design and is useless if you have a framework that follows a synchronous approach.

On the Java side Virtual Thread or reading memory from the Buffer is a solution, on the go side goroutines, but on the haxe side there is no current or planned way we can achieve this.

If Haxe at least buffers the bytes and provides a “remainingBytes” derivative API, there will be no problem.

How you architect your framework is up to you and not really relevant to this debate. If it works for you, then great. You are however sharing opinions about macros that appear to be rooted in misconceptions of what macros are even about, which above all is correctness. Ordinarily I wouldn’t even care much, but if it’s in one of the busiest threads about Haxe’s status and you brush off one of its most outstanding features as some game dev optimization that is useless for web development, you’re really not doing anyone a favor.


As for you building a web server your way, I sympathise with your struggles, but you’ve picked a whole number of very specific constraints for yourself and you cannot expect the standard library of all places to solve all those self-induced problems for you.

Also ThreadServer is easy enough to port to other platforms. It was first added 20 years ago on neko and that’s how long Haxe developers have been writing concurrent servers without being “forced into a blocking ‘1 thread = 1 socket’ model”. If it fits your use case it is trivially ported elsewhere. If not, then not. It’s all fine. But to suggest that situation that you got yourself into is somehow inevitable for anyone wanting to write a web server in Haxe is grossly misleading.

2 Likes

I have to disagree with the premise that ThreadServer is the standard, easily adopted solution. If you examine the actual Haxe ecosystem, the vast majority of developers clearly prefer targeting Node.js or relying on platform-specific native libraries for HTTP servers. Even a foundational project like OpenFL uses Node.js just to spin up a simple HTTP server.

This is not a misconception specific to me, nor is it a “self-induced” problem. Almost all currently published native Haxe HTTP servers face the exact same blocking limitations I mentioned. Furthermore, a quick GitHub search reveals that virtually no active HTTP projects are actually utilizing the cpp.net.ThreadServer architecture.

The observable reality of how the community builds servers simply doesn’t align with the idea that this is a solved problem in the standard library.

Looking at the search results for cpp.net.ThreadServer: Setting aside the fact that virtually no HTTP servers utilize it, the latest repository updates in that search are literally from 9 to 10 years ago!

Even core-haxe/http explicitly requires Node.js for its server implementation:

I do not fully agree about the DX growing as a side effect of popularity … yes that happens like it happened with Java but some languages grew out of very good DX, Elm, Kotlin, Rust come to mind. Anyway I agree with most of your considerations :wink: