Introducing snake-server, a simple local web server for Haxe

Many programming languages, or their communities of library authors, offer a way to quickly start a web server in a specific local directory with just one simple command. For instance, Python users can run python3 -m http.server 8000, or Node.js users can install the http-server module globally and run http-server -p 8000. For reference, here’s a big list of http static server one-liners for a variety of languages and their run-times.

When working in Haxe, and compiling to JavaScript in HTML pages, I often need to launch an HTML file in a web browser. It’s always best to use a server instead of double-clicking an HTML file in your operating system’s file explorer because web browsers often behave differently with local files versus content originating from web servers. I typically reach for the Node.js command that I mentioned above. Similarly, the command line build tools used by OpenFL also use the same http-server module with Node.js when you run the lime test html5 command to run your project in a browser.

As a Haxe developer, I can’t help but feel like the Haxe community should be able to reach for a pure Haxe solution that starts a local web server, and it shouldn’t rely on another language’s tooling.

Last week, with that idea in mind, I started working on snake-server 🐍, a Haxe library (built on sys.net.Socket from the Haxe standard library) that can be used to start a web server in a specific directory for local development — all with one quick command.

haxelib run snake-server

It uses port 8000 on local IP 127.0.0.1 with protocol HTTP/1.0 by default, in the current working directory. However, there are command line options for customizing all four of those things.

Install snake-server with a one-time command:

haxelib install snake-server

It’s called snake-server because I actually ported Python’s http.server and socketserver modules to Haxe. To be clear, not as externs, but as pure Haxe that works on any sys target, including the Haxe interpreter, HashLink, hxcpp, and Neko. I figured an official Python module would have the most important edge cases covered, and I could see it was created with a similar raw TCP socket API that’s available in Haxe, so it would be easy enough to port that existing code to Haxe and get a solid solution working as quickly as possible.

The server handles each request in a separate thread. I skipped this part at first because it didn’t seem necessary. However, as I finished implementing HTTP/1.1 support, I realized it was vital because keep-alive requests would block on the final socket read, until timeout, which would block other socket writes from completely flushing, which made pages appear to partially load for several seconds, and then finish all at once after the timeout delay. Each request in a separate thread made everything snappy while supporting the keep-alive optimization.

In your terminal, you can exit the server with the standard Ctrl+C keyboard shortcut. Occasionally, if you exit snake-server, and then try to start snake-server again on the same port too quickly, it’ll say that the port is still in use. It should become available within seconds, though. I think other languages may provide a way to ensure this doesn’t happen, but I’m not sure if that’s catching the Ctrl+C interrupt signal, or if it involves tweaking the socket configuration in some way. I don’t think Haxe exposes what I need, but maybe I’m wrong? Let me know if you know how to fix this issue.

The snake-server source code is on GitHub. Bug fix PRs are welcome, especially for things that behave differently than the original Python implementation. However, please create an issue to ask before submitting new feature PRs. I plan to keep the Haxe code as close to the original Python code as I possibly can, to avoid future maintenance headaches if I port important changes from future Python updates.

I hope that the Haxe community finds snake-server to be useful for their everyday web development needs. If you like snake-server, please consider a monthly donation towards my open source contributions on my GitHub Sponsors page. Thank you!

About Josh Tynjala

Josh Tynjala is a frontend software developer, open source contributor, karaoke enthusiast, and he likes bowler hats. Josh develops Feathers UI, a user interface component library for creative apps, and he is a member of the OpenFL leadership team. One of his side projects is Logic.ly, a digital logic circuit simulator for education. You should follow Josh on Mastodon.

Discussion

  1. Josh Tynjala

    Ian Harrigan, who develops Haxe UI, mentioned the nekotools server command to me, which also starts a local web server (using Neko, obviously). I wasn’t aware of that one!

    However, it is worth noting that Neko has been considered deprecated, and not actively maintained, since 2021. Snake Server runs on the Haxe interpreter, so it will continue to work if Neko is ever removed from the default Haxe installation.

    Additionally, snake-server has some advanced options that may provide a better development experience, such as the ability to enable CORS headers and disable browser caching.

Leave a Reply

Your email address will not be published. Required fields are marked *