Getting Started
crashlink is a pure-Python toolkit for HashLink bytecode: disassembly, decompilation, patching, and reserialisation. This page gets you from nothing installed to poking around a .hl file. For the full CLI/REPL command reference, see CLI and REPL.
Installing
The core package has zero dependencies, so a plain install is enough to disassemble and patch bytecode:
pip install crashlink
If you use uv, you can run it without installing anything into a project at all:
uvx crashlink game.hl
or install it as a standalone tool:
uv tool install crashlink
The [extras] group
A handful of features are gated behind an optional dependency group, so the base install stays dependency-free. Install it with:
pip install crashlink[extras]
# or
uv tool install crashlink[extras]
[extras] pulls in:
tqdm, for progress bars during load/save of large bytecode filesIPython, for a nicerpyrepldrop-in Python shellpygments, for syntax-highlighted pseudocode outputliefandcapstone, for the HL/C binary-inspection and disassembly toolingmcp, to run crashlink as an MCP serverPySide6andgraphviz(Python bindings), for the GUIkeystone-engine, for inline x86 assembly
There's also a smaller [gui] group (PySide6 + graphviz) if all you want is the graphical inspector without the rest.
None of this is required to use the CLI or the library for basic disassembly and patching. Without tqdm installed, load/save just falls back to plain status lines on stderr instead of a progress bar.
Graphviz (system dependency)
Rendering control flow graphs (the cfg REPL command, or the embedded CFG viewer in the GUI) needs the actual Graphviz binaries on your PATH, not just the Python bindings pulled in by [extras]. Install it with your platform's package manager:
- Windows:
choco install graphviz - macOS:
brew install graphviz - Debian/Ubuntu:
sudo apt install graphviz - Arch:
sudo pacman -S graphviz - Fedora:
sudo dnf install graphviz
If you don't need CFG diagrams, you can skip this entirely.
Your first five minutes
Point crashlink at a bytecode file with no subcommand and it opens the interactive REPL:
$ crashlink game.hl
crashlink> funcs
f@22 static Clazz.main () -> Void (from Clazz.hx)
f@23 Clazz.method (Clazz) -> I32 (from Clazz.hx)
crashlink> fn 22
f@22 static Clazz.main () -> Void (from Clazz.hx)
Reg types:
0. Void
Ops:
0. Ret {'ret': 0} return
funcs lists every function and native in the file (stdlib functions are hidden by default). fn <findex> disassembles one to its raw opcode listing. Functions, types, globals, and strings are all addressed by index throughout crashlink: f@<findex>, t@<tIndex>, g@<gIndex>, s@<index>.
If you'd rather script against it, the same load-and-inspect flow works from Python:
from crashlink import *
code = Bytecode.from_path("game.hl")
func = code.fn(22) # 22 and 240 are typical compiler-generated entry points
if func:
print(disasm.func(code, func))
From here, decomp <findex> in the REPL gives you a pseudo-Haxe decompilation instead of raw opcodes, and cfg <findex> renders a control flow graph if Graphviz is installed. The full command list, CLI flags, and a longer worked session live on the CLI and REPL page. For how the pieces underneath these commands fit together, see the architecture overview.