node-xmlrpc
A pure JavaScript XML-RPC client and server for Node.js, with no native C dependencies for parsing or building XML.
Repository Health
Technical Analysis
xmlrpc is a pure JavaScript implementation of the XML-RPC protocol for Node.js, providing both a client for making method calls and a server for receiving them. Because the XML parsing (via sax) and XML building (via xmlbuilder) are both pure-JavaScript libraries, the package installs without any C bindings or native build step, which matters for XML-RPC in particular since many alternative implementations lean on libxml or expat bindings.
The client wraps Node’s http/https modules directly, serializing method calls to XML-RPC’s parameter types (strings, ints, doubles, booleans, dates, base64 buffers, structs, and arrays) and streaming the response through a SAX-based deserializer. The server is a thin EventEmitter over http.createServer: it deserializes incoming XML-RPC method calls and re-emits them as named events, so handling a method is a matter of listening for its name and calling back with a result or fault. Support for ISO-8601 date formatting options, cookie persistence across calls, and user-defined custom types (for encoding values XML-RPC doesn’t natively support) round out the feature set.
The project has been effectively feature-complete and in maintenance mode since its last tagged release in 2016, but it remains the de facto standard XML-RPC library for Node.js and is still depended on by tools that speak to legacy XML-RPC endpoints (WordPress, Trac, MoinMoin, and other systems that predate JSON-based APIs).
What You Get
- An XML-RPC client (
xmlrpc.createClient/createSecureClient) that serializes method calls and parses method responses over HTTP or HTTPS - An XML-RPC server (
xmlrpc.createServer/createSecureServer) built on Node’s http/https modules, emitting incoming calls as named events - A streaming SAX-based deserializer that decodes XML-RPC’s full value model: strings, ints, doubles, booleans, dates, base64, structs, and nested arrays
- Configurable ISO-8601 date formatting (colons, hyphens, local vs. UTC, milliseconds, UTC offset) to match the conventions of the server you’re talking to
- Optional cookie support that persists
Set-Cookievalues across client calls and exposesgetCookie/setCookie - A
CustomTypebase class for encoding values XML-RPC doesn’t support natively, with a serializer you can override per type
Common Use Cases
- Calling legacy XML-RPC APIs from Node.js — WordPress’s
xmlrpc.php, Trac, MoinMoin, and other systems that never migrated to REST/JSON - Building a lightweight XML-RPC server so a Node.js service can be called by older clients or CI systems that only speak XML-RPC
- Bridging a modern Node.js backend to legacy infrastructure during a phased migration off an XML-RPC-based system
- Scripting bulk operations against XML-RPC endpoints (e.g. WordPress content migration/automation tools) without shelling out to another language’s XML-RPC client
Under The Hood
Architecture
The library is organized as a small set of single-responsibility modules under lib/: client.js and server.js handle the HTTP transport and public API, while serializer.js and deserializer.js handle the XML-RPC wire format in isolation from any I/O. Client#methodCall (lib/client.js) builds request options (merging in default headers, optional basic-auth, and an optional Cookies processor), serializes the call via Serializer.serializeMethodCall, and streams the response body into a Deserializer instance, which itself wraps a sax streaming parser and drives a small explicit stack machine (onOpentag/onClosetag/endArray/endStruct, etc.) to reconstruct nested XML-RPC values without buffering the whole document. Server (lib/server.js) is a thin EventEmitter subclass over http.createServer: each incoming call is deserialized and re-emitted under the method’s own name, with a NotFound event as a catch-all, so handler registration is just server.on('methodName', ...). The serializer (serializer.js) takes the opposite approach from a naive recursive walk — it uses an explicit work-stack (serializeValue) to serialize potentially deep/cyclic-shaped structs and arrays without blowing the JS call stack. Nothing here breaks in isolation from the rest of the app; the core abstraction that would ripple outward if changed is the shared XML-RPC value encoding between serializer.js and deserializer.js, since client and server both depend on that encoding being symmetric.
Tech Stack
The runtime dependency surface is intentionally minimal: sax (a pure-JS streaming XML parser) for deserialization and xmlbuilder for serialization, with no native/C-addon dependencies at all — a deliberate design choice called out in the README as “pure JavaScript.” It targets plain Node.js http/https (no framework), has no build step (no TypeScript, no bundler), and ships CommonJS modules directly from lib/. devDependencies list only vows as the test runner, and CI historically ran through Travis CI (badge still in the README, though the project predates GitHub Actions).
Code Quality
Testing uses vows, an older BDD-style async test framework, with test files (client_test.js, server_test.js, serializer_test.js, deserializer_test.js, cookies_test.js, date_formatter_test.js) that mirror the lib/ modules one-to-one and include XML fixture files under test/fixtures/ for good- and bad-input cases. There is no TypeScript and no type declarations; all code is plain ES5-style JavaScript (var, prototype-based classes, no arrow functions), consistent with a codebase whose most recent substantive commits predate widespread ES6 adoption in the Node ecosystem. Error handling is explicit rather than swallowed — the deserializer accumulates parse errors onto this.error and routes them through a single onError callback path, and the client enriches transport errors with the raw request/response/body to aid debugging. No linter or formatter config is present in the repo.
What Makes It Unique The library’s distinguishing choice is going all-in on pure JavaScript for both halves of XML processing (parsing via sax, building via xmlbuilder) at a time when many equivalent tools reached for native XML bindings — this removes an entire class of install/build failures for XML-RPC specifically. The deserializer’s use of an explicit stack machine driven by SAX events (rather than building a full DOM tree and then walking it) lets it decode arbitrarily nested XML-RPC structs/arrays with streaming, constant-overhead parsing. It isn’t attempting novel protocol design — it implements the XML-RPC spec faithfully, including its more awkward corners like ISO-8601 date variants and base64 payloads — but as one of the only actively-referenced pure-JS XML-RPC implementations for Node, it fills a narrow, otherwise poorly-served niche.
Used by 2 apps in this directory
Activepieces
Automation · AI Assistants
Open-source AI automation platform that converts 280+ workflow integrations into MCP servers for LLMs, with no-code builders and TypeScript extensibility.
Automatisch
Automation · No Code Platforms
Self-hosted, no-code workflow automation that keeps your data on your own servers—a privacy-first alternative to Zapier with 90+ integrations.