libxslt-next
v1.0.11
Published
Node.js bindings for libxslt with Node.js 22/24 support - Modern fork with updated dependencies
Downloads
639
Maintainers
Readme
libxslt-next
Node.js bindings for libxslt, compatible with libxmljs2.
A modern, maintained fork of node-libxslt with updated dependencies, TypeScript types, and support for current Node.js LTS releases.
- Node.js 22.x and 24.x (Node 20 is not supported —
[email protected]requires Node ≥ 22) - Linux (glibc & musl/Alpine), macOS (Intel & Apple Silicon), Windows — all built from source
- TypeScript types included
- Install paths containing spaces are supported (Linux, macOS and Windows)
Installation
npm install libxslt-nextFrom source:
git clone https://github.com/mariuso/node-libxslt-next.git
cd node-libxslt-next
git submodule update --init
npm install
npm testManual rebuild: if you need to rebuild the native bindings:
npm run rebuildThe native addon is compiled on install, so a C/C++ toolchain and Python 3 must be present (see Environment compatibility below).
Alpine / musl
The native addon is built from source on install, so the build toolchain must be present. On Alpine (musl libc) install it first:
apk add --no-cache build-base python3This is also required in Alpine-based Docker images, e.g. node:24-alpine:
FROM node:24-alpine
RUN apk add --no-cache build-base python3
# ... npm installVersions before 1.0.10 failed to load on musl with
Error loading shared library xmljs.node ... (ERR_DLOPEN_FAILED). 1.0.10 adds an rpath so the addon resolves its libxmljs2 dependency on musl.
Basic usage
JavaScript
var libxslt = require('libxslt-next');
libxslt.parse(stylesheetString, function(err, stylesheet){
var params = {
MyParam: 'my value'
};
// 'params' parameter is optional
stylesheet.apply(documentString, params, function(err, result){
// err contains any error from parsing the document or applying the stylesheet
// result is a string containing the result of the transformation
});
});TypeScript
import * as libxslt from 'libxslt-next';
import { Stylesheet, ApplyOptions } from 'libxslt-next';
// Parse stylesheet with type safety
libxslt.parse(stylesheetString, (err, stylesheet: Stylesheet | undefined) => {
if (err) {
console.error('Parse error:', err);
return;
}
if (!stylesheet) return;
const params = {
MyParam: 'my value'
};
const options: ApplyOptions = {
outputFormat: 'string'
};
// Apply with full type checking
stylesheet.apply(documentString, params, options, (err, result) => {
if (err) {
console.error('Apply error:', err);
return;
}
// result is properly typed as string | libxmljs.Document
console.log('Transform result:', result);
});
});
// Synchronous usage with types
const stylesheet: Stylesheet = libxslt.parse(stylesheetString);
const result: string = stylesheet.apply(documentString);Libxmljs integration
libxslt-next depends on libxmljs2 in the same way that libxslt depends on libxml. This dependancy makes possible to bundle and to load in memory libxml only once for users of both libraries.
The libxmljs module required by libxslt-next is exposed as require('libxslt-next').libxmljs. This prevents depending on libxmljs twice which is not optimal and source of weird bugs.
It is possible to work with libxmljs documents instead of strings:
var libxslt = require('libxslt-next');
var libxmljs = libxslt.libxmljs;
var stylesheetObj = libxmljs.parseXml(stylesheetString, { nocdata: true });
var stylesheet = libxslt.parse(stylesheetObj);
var document = libxmljs.parseXml(documentString);
stylesheet.apply(document, function(err, result){
// result is now a libxmljs document containing the result of the transformation
});
This is only useful if you already needed to parse a document before applying the stylesheet for previous manipulations. Or if you wish to be returned a document instead of a string for ulterior manipulations. In these cases you will prevent extraneous parsings and serializations.
Includes
XSL includes are supported but relative paths must be given from the execution directory, usually the root of the project.
Includes are resolved when parsing the stylesheet by libxml. Therefore the parsing task becomes IO bound, which is why you should not use synchronous parsing when you expect some includes.
Sync or async
The same parse() and apply() functions can be used in synchronous mode simply by removing the callback parameter. In this case if a parsing error occurs it will be thrown.
var lixslt = require('libxslt-next');
var stylesheet = libxslt.parse(stylesheetString);
var result = stylesheet.apply(documentString);
When a callback is given, parse() and apply() run the transform on the main
thread but invoke the callback on a later tick of the event loop (via
setImmediate). The call returns immediately and errors are delivered to the
callback instead of being thrown.
Note on parallelism: earlier versions ran the libxslt computation on a libuv worker thread. That was removed because libxslt/libxml2 share global state with libxmljs2 and are not safe to run off the main thread, which caused intermittent empty results and crashes. The callback form therefore does not parallelize CPU work across threads — it only defers it. If you need true parallelism for CPU-bound transforms, run libxslt-next inside your own
worker_threadspool.
A small benchmark is available in the project (it always runs the same small transformation a few thousand times):
node benchmark.jsGuidance:
- the synchronous and callback forms do the same amount of work; the callback form only differs in that it yields to the event loop before running.
- of course you can use synchronous simply to reduce code depth.
- DO NOT USE synchronous parsing if there are includes in your XSL stylesheets (include resolution makes parsing IO-bound).
Environment compatibility
Node.js Support: This package supports Node.js 22.x and 24.x LTS versions.
Node.js 20 is not supported because [email protected] requires Node.js >= 22.
Platform Support:
- ✅ Linux (64-bit, glibc and musl/Alpine)
- ✅ macOS (Intel & Apple Silicon)
- ✅ Windows (64-bit)
Build Requirements: libxslt-next depends on node-gyp for native compilation. You will need:
- Node.js 22.0.0 or higher
- Python 3.x
- C++ build tools (Visual Studio Build Tools on Windows). Note: node-gyp does not yet detect Visual Studio 2026 (node-gyp#3282); use Visual Studio 2022 build tools.
Dependencies: This package uses:
- libxmljs2 for XML parsing (replaces deprecated libxmljs)
- NaN 2.22.2+ for Node.js API compatibility
- Bundled libxslt (no system dependencies required)
TypeScript Support: This package includes built-in TypeScript definitions:
- No need to install separate
@typespackages - Full type safety for all API methods
- Compatible with TypeScript 3.0+
- Auto-completion and IntelliSense support in modern IDEs
API Reference
Node.js bindings for libxslt compatible with libxmljs
libxslt.libxmljs
The libxmljs module. Prevents the need for a user's code to require it a second time. Also prevent weird bugs.
Kind: static property of libxslt
libxslt.parse(source, [callback]) ⇒ Stylesheet
Parse a XSL stylesheet
If no callback is given the function will run synchronously and return the result or throw an error.
Kind: static method of libxslt
Returns: Stylesheet - Only if no callback is given.
| Param | Type | Description | | --- | --- | --- | | source | string | Document | The content of the stylesheet as a string or a libxmljs document | | [callback] | parseCallback | The callback that handles the response. Expects err and Stylesheet object. |
libxslt.parseFile(sourcePath, callback)
Parse a XSL stylesheet
Kind: static method of libxslt
| Param | Type | Description | | --- | --- | --- | | sourcePath | stringPath | The path of the file | | callback | parseFileCallback | The callback that handles the response. Expects err and Stylesheet object. |
libxslt~Stylesheet
Kind: inner class of libxslt
new Stylesheet(stylesheetDoc, stylesheetObj)
A compiled stylesheet. Do not call this constructor, instead use parse or parseFile.
store both the source document and the parsed stylesheet if we don't store the stylesheet doc it will be deleted by garbage collector and it will result in segfaults.
| Param | Type | Description | | --- | --- | --- | | stylesheetDoc | Document | XML document source of the stylesheet | | stylesheetObj | Document | Simple wrapper of a libxslt stylesheet |
stylesheet.apply(source, [params], [options], [callback]) ⇒ string | Document
Apply a stylesheet to a XML document
If no callback is given the function will run synchronously and return the result or throw an error.
Kind: instance method of Stylesheet
Returns: string | Document - Only if no callback is given. Type is the same as the source param.
| Param | Type | Description | | --- | --- | --- | | source | string | Document | The XML content to apply the stylesheet to given as a string or a libxmljs document | | [params] | object | Parameters passed to the stylesheet (http://www.w3schools.com/xsl/el_with-param.asp) | | [options] | applyOptions | Options | | [callback] | applyCallback | The callback that handles the response. Expects err and result of the same type as the source param passed to apply. |
stylesheet.applyToFile(sourcePath, [params], [options], callback)
Apply a stylesheet to a XML file
Kind: instance method of Stylesheet
| Param | Type | Description | | --- | --- | --- | | sourcePath | string | The path of the file to read | | [params] | object | Parameters passed to the stylesheet (http://www.w3schools.com/xsl/el_with-param.asp) | | [options] | applyOptions | Options | | callback | applyToFileCallback | The callback that handles the response. Expects err and result as string. |
libxslt~parseCallback : function
Callback to the parse function
Kind: inner typedef of libxslt
| Param | Type | | --- | --- | | [err] | error | | [stylesheet] | Stylesheet |
libxslt~parseFileCallback : function
Callback to the parseFile function
Kind: inner typedef of libxslt
| Param | Type | | --- | --- | | [err] | error | | [stylesheet] | Stylesheet |
libxslt~applyOptions
Options for applying a stylesheet
Kind: inner typedef of libxslt
Properties
| Name | Type | Description | | --- | --- | --- | | outputFormat | String | Force the type of the output, either 'document' or 'string'. Default is to use the type of the input. | | noWrapParams | boolean | If true then the parameters are XPath expressions, otherwise they are treated as strings. Default is false. |
libxslt~applyCallback : function
Callback to the Stylesheet.apply function
Kind: inner typedef of libxslt
| Param | Type | Description | | --- | --- | --- | | [err] | error | Error either from parsing the XML document if given as a string or from applying the styleshet | | [result] | string | Document | Result of the same type as the source param passed to apply |
libxslt~applyToFileCallback : function
Callback to the Stylesheet.applyToFile function
Kind: inner typedef of libxslt
| Param | Type | Description | | --- | --- | --- | | [err] | error | Error either from reading the file, parsing the XML document or applying the styleshet | | [result] | string | |
documented by jsdoc-to-markdown.
