Type-Safe JavaScript Calls with Haxe Externs and Conditional Compilation
Learn how to use Haxe externs to get compile-time type safety when calling JavaScript libraries, with a lodash chunk example and conditional compilation tips.
05 Apr 2026, 05:20 UTC

Problem: Calling JavaScript libraries without losing type safety
When a Haxe project needs to use an existing JavaScript library, plain untyped calls bypass the compiler’s checks. A typo or mismatched argument can slip through and only appear at runtime, making debugging harder.
Solution: Declare externs and use conditional compilation
Haxe externs let you describe the shape of a JavaScript API in Haxe syntax. The compiler then type‑checks every call against that description, emitting plain JavaScript calls with zero runtime overhead. The @:build metadata lets you include or exclude code per target, so the same source file can stay pure Haxe for other platforms while providing JS‑specific externs.
Worked example: Using lodash’s _.chunk with an extern
// src/LodashExterns.hx
extern @:js(true) class Lodash {
// _.chunk(array, size)
public static function chunk(arr:Array, size:Int):Array>;
}
// src/Main.hx
class Main {
static function main() {
var data = [1,2,3,4,5,6,7];
var grouped = Lodash.chunk(data, 3);
trace(grouped); // [[1,2,3],[4,5,6],[7]]
}
}
To compile for JavaScript, create an build.hxml file:
-js bin/main.js
-main Main
-lib lodash extern // assuming you have an extern library installed via haxelib
-D js
Run the build from the project root:
haxe build.hxmlThe compiler will emit
bin/main.js. Inspecting the output shows a direct call to the lodash function:// bin/main.js (generated) function main() { var data = [1,2,3,4,5,6,7]; var grouped = Lodash.chunk(data, 3); console.log(grouped); } main();If you also compile to another target (e.g., C++), you can guard the extern with @:build:
// src/LodashExterns.hx #if js extern @:js(true) class Lodash { public static function chunk(arr:Array, size:Int):Array>; } #endThe
#if jsblock is only included when the-D jsflag is present, keeping the file clean for other targets.Limitations and verification
Externs are a compile‑time contract; if the Haxe description does not match the actual JavaScript library version, the program will still compile but may throw errors at runtime. To reduce this risk:
- Keep extern definitions in sync with the library’s typings or documentation.
- Run
haxe --versionto confirm you are using a recent compiler (e.g., 4.3.0+). - After building, open the generated JavaScript file and verify that the extern names appear exactly as they are called in the library (no extra mangling).
Another point to watch is number handling: Haxe’s Float maps to JavaScript’s Number, but when targeting strict‑int languages the same code may truncate values. Test edge‑case values when sharing code across targets.
Actionable closing
Start by writing a small extern for the function you need, add it to your hxml file, and compile. Inspect the generated JavaScript to confirm the call looks exactly like a plain library call. With the extern in place you gain compile‑time safety without sacrificing the ability to use the vast JavaScript ecosystem.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.