- Search GitHub Issues first to avoid duplicates
- Provide sufficient information: version, environment, steps to reproduce
- Include failing test cases when possible
The CI build verifies tests, coverage, and code style. Run locally with npm test.
Requirements:
- Documentation: Every exported API needs TypeDoc comments
- Code Coverage: 98% lines, 90% branches - check
coverage/lcov-report/index.html - Linting: Must pass ESLint (Airbnb TypeScript config)
- Node.js 18+
- Emscripten SDK (compiles libxml2 C to WebAssembly)
- C toolchain: autoconf, automake, libtool, pkg-config
Provides pre-configured environment with all dependencies.
VS Code:
- Install Docker Desktop and Dev Containers extension
- Clone and open repository:
git clone https://github.com/jameslan/libxml2-wasm.git code libxml2-wasm
- Press
F1→ "Dev Containers: Reopen in Container" - Wait for setup to complete (auto-initializes submodules and installs dependencies)
WebStorm/IntelliJ: See DevContainer docs
Install C toolchain:
- macOS:
brew install autoconf automake libtool pkg-config - Ubuntu/Debian:
sudo apt-get install autoconf automake libtool pkg-config libatomic1 - Fedora/Enterprise Linux:
sudo dnf install autoconf automake libtool pkg-config libatomic
Install Emscripten:
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.shBuild:
git clone https://github.com/jameslan/libxml2-wasm.git
cd libxml2-wasm
git submodule update --init --recursive
npm install
npm run buildWindows: Use DevContainer (Option 1) or WSL 2 with Linux instructions. Native Windows is not supported due to shell command differences.
Run the full build after cloning or when changing libxml2 configuration:
npm run build # Full build: WASM + TypeScript
npm test # Verify everything worksThis compiles libxml2 C code into WebAssembly and TypeScript into JavaScript.
Most common workflow - editing src/*.mts or test/**/*.mts:
npm run watch # Auto-recompile TypeScript on save
# OR
npm run tsc # Compile TypeScript once
# and always
npm test # Tests + coverage + lintingTwo files control WASM exports:
Lists libxml2 C functions (with underscore prefix per Emscripten convention):
_xmlNewDoc
_xmlAddChild
_xmlFreeDoc
...
Lists Emscripten runtime functions for memory management:
HEAP32
UTF8ToString
addFunction
...
Adding new functions:
- Find the function in libxml2 docs
- Add to
binding/exported-functions.txtwith underscore:_xmlFunctionName npm run linkto relink WASM- Add TypeScript wrapper in
src/libxml2.mts - Write tests in
test/ - Build and run tests to verify everything works
Each call to moduleLoader() creates a new WASM module instance with its own separate memory space. Pointers from one
instance won't work in another.
Incorrect approach:
// -- mynewfeature.mts --
import {xmlSaveDoc} from './libxml2.mjs';
import moduleLoader from "./libxml2raw.mjs";
import {XmlDocument} from './document.mjs';
const libxml2 = await moduleLoader(); // Creates a NEW instance of libxml2 with its own memory space
const ptr = libxml2._malloc(100); // Memory in NEW instance
const doc = XmlDocument.fromString('<root/>'); // This uses the "global" instance of libxml2
xmlSaveDoc(ptr, doc._ptr); // FAIL: the ptr and the doc are from different instancesVS Code: Three launch configurations are available in .vscode/launch.json:
- Mocha: All Tests - Debug all tests
- Mocha: Current File - Debug a single test file
- Mocha: Grep Tests - Debug specific tests by name pattern
WebStorm/IntelliJ: Works out of the box with the built-in debugger.
To debug the libxml2 C code build the debug version:
npm run build:debug # Build WASM with debug symbols (-g) and no optimizations (-O0)VS Code DevContainer: Works by default. You can step through and set breakpoints in C code directly.
Local VS Code setup: Install the WebAssembly DWARF Debugging extension for C code debugging support.
WebStorm/IntelliJ: Not supported at this time.
Always use using keyword or call .dispose():
using doc = XmlDocument.fromString('<root/>');
// Automatically disposed"emcc: command not found"
→ Activate Emscripten: source /path/to/emsdk/emsdk_env.sh
Questions? GitHub Discussions | Bugs? GitHub Issues