log4js-node: Configurable Category-Based Logging for Node.js
A port of log4js to node.js
At a glance
- What is it?
- log4js-node is a Node.js logging library ported from the Java-era log4j framework, providing configurable appenders, log categories, and rolling file output for server-side JavaScript. It is aimed at Node.js backend developers who need structured, production-grade logging that goes beyond console.log without reaching for a heavyweight observability stack.
- Who is it for?
- log4js-node is a good fit for Node.js projects that need category-based log routing, file rolling, and express/connect integration under a single, established package. It is not a good fit for teams that want structured JSON output to a centralized log aggregator by default, because that capability requires choosing and configuring the appropriate optional appender package separately.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 23 days ago.
- What is it written in?
- Mainly JavaScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What log4js-node Provides and Who Uses It
log4js-node addresses the gap between Node.js's built-in console and a full observability platform. The standard console object writes to stdout or stderr with no structured categories, no level filtering, no file output, and no way to enable detailed logging for one part of an application while suppressing it in another. log4js-node adds all of those capabilities while keeping a simple API for the common case.
The library is aimed at backend Node.js developers writing APIs, workers, or any server-side process where production log output needs to go to a file, a remote service, or a structured format that can be queried later. The README notes explicitly that the library intentionally defaults to producing no output so that libraries that import log4js-node do not surprise their consumers with unexpected logs. This design decision means that log4js-node can be included in a library package without risk, which is a different philosophy from some competitors that log to stdout immediately on import.
The README also warns that despite the similar name to the Java library log4j, thinking that log4js-node will behave the same way will bring confusion. The two share a conceptual model (appenders, categories, levels) but the configuration syntax and available appender types differ. Developers migrating from a Java background should treat log4js-node as a distinct system that borrows the vocabulary, not a port with identical semantics.
Install and Minimal Setup
Install log4js-node with npm:
npm install log4jsThe package name on npm is log4js, not log4js-node. The simplest possible setup requires only two lines after the require call:
var log4js = require("log4js");
var logger = log4js.getLogger();
logger.level = "debug";
logger.debug("Some debug messages");This outputs to stdout with colored formatting. The output format includes a timestamp, the level, the category name, and the message:
[2010-01-17 11:43:37.987] [DEBUG] [default] - Some debug messagesWithout setting the level, the logger produces no output because the default category's level is OFF. This is documented behavior, not a configuration bug.
Appenders and Category Configuration
The main configuration surface in log4js-node is the appender and category system. Appenders define where log output goes; categories define which appenders a given logger uses and at what minimum level. Multiple appenders can be assigned to a single category, so a single log call can simultaneously write to a file and send a notification to Slack. The configuration object passed to log4js.configure() maps appenders by name and assigns them to categories:
const log4js = require("log4js");
log4js.configure({
appenders: { cheese: { type: "file", filename: "cheese.log" } },
categories: { default: { appenders: ["cheese"], level: "error" } },
});
const logger = log4js.getLogger("cheese");
logger.trace("Entering cheese testing");
logger.debug("Got cheese.");
logger.info("Cheese is Comté.");
logger.warn("Cheese is quite smelly.");
logger.error("Cheese is too ripe!");
logger.fatal("Cheese was breeding ground for listeria.");In this configuration, the category level is set to error, so only logger.error and logger.fatal calls produce output in the file. The log levels in ascending order are: trace, debug, info, warn, error, fatal. Setting a category to warn means that trace, debug, and info messages are silently discarded.
The file appender supports rolling by file size or by date. This is controlled by appender type and options in the configuration object. The README does not include the rolling configuration inline, but the documentation site at log4js-node.github.io/log4js-node/ covers it.
TypeScript Support and Connect Middleware
log4js-node ships TypeScript declarations in the types/ directory. The types file is referenced as the main types entry in package.json. Importing log4js in a TypeScript project provides full type coverage without a separate @types package:
import * as log4js from "log4js";
log4js.configure({
appenders: { cheese: { type: "file", filename: "cheese.log" } },
categories: { default: { appenders: ["cheese"], level: "error" } },
});
const logger = log4js.getLogger();
logger.level = "debug";
logger.debug("Some debug messages");For Express and connect-based applications, log4js-node provides a connectLogger middleware that logs incoming HTTP requests. The category and level for HTTP request logging are configured separately from application-level loggers, allowing request logs to go to a different appender or file.
The package.json lists the minimum Node.js engine version as 8.0.0. The current version of the package is 6.9.1. Most active Node.js deployments run a version well above 8.0.0, so this constraint is not a practical issue.
Optional Appenders and Extensibility
The README documents a significant number of optional appenders maintained as separate packages under the log4js-node GitHub organization. These include SMTP for email alerts, GELF for Graylog, Loggly, Logstash over UDP and HTTP, logFaces over UDP and HTTP, RabbitMQ, Redis, Hipchat, Slack, mailgun, and InfluxDB. Each is installed separately and referenced by type name in the appender configuration.
This modular design keeps the core log4js package lean. An application that only needs file logging does not install the Slack or RabbitMQ package. The trade-off is that finding, installing, and keeping those optional packages updated is the application developer's responsibility. The optional packages are maintained on separate timelines from the core package.
For library authors who want to support log4js-node logging without making it a required dependency, the README points to log4js-api, a separate package that provides the logger interface without the runtime implementation. Applications that include log4js-node will see log output; those that do not will see nothing.
Limitations and When to Consider Alternatives
log4js-node's configuration syntax is more verbose than some alternatives. Defining an appender, naming it, assigning it to a category, and setting a level requires three separate configuration keys. A developer who wants a single call to get structured JSON output to stdout will find Winston or Pino require less initial configuration for that specific case.
Pino, in particular, is designed for high-throughput JSON logging and benchmarks significantly faster than log4js-node in serialization-heavy workloads. If the application logs thousands of messages per second and latency matters, Pino's architecture (which uses a child process for serialization) has a measurable advantage. log4js-node's architecture is synchronous in its core path, which is simpler to reason about but not optimal for extreme logging throughput.
The library carries a migration guide from version 1.x to 2.x and a separate guide for version 3.x changes. Projects upgrading across multiple major versions will need to review both. The README points to log4js-node.github.io/log4js-node/ for the full documentation and migration guide.
log4js-node also does not provide a way to dynamically change a category's log level at runtime without reloading the configuration. Applications that want to increase verbosity for a specific category during a debugging session and then reduce it again must either restart with a new configuration or implement their own level-override mechanism on top of the library's API.
Editorial conclusion
log4js-node is a good fit for Node.js projects that need category-based log routing, file rolling, and express/connect integration under a single, established package. It is not a good fit for teams that want structured JSON output to a centralized log aggregator by default, because that capability requires choosing and configuring the appropriate optional appender package separately. Before adopting it, note that the default log level for the default category is OFF, so any code that imports the library without explicit configuration will produce no output until a level is set.
Frequently asked questions
Does log4js-node output anything by default?
No. The README states explicitly that the default category level is OFF so the library can safely be used in shared libraries without producing unexpected output. To enable logging, set a level on the logger directly (logger.level = "debug") or specify a level in the categories section of a log4js.configure() call.
How do I write logs to a file that rolls over in log4js-node?
Configure the appenders section of log4js.configure() with a file appender by setting type to "file" and providing a filename. File rolling by size or date is controlled by additional options on the appender object. The full rolling configuration options are documented on the log4js-node documentation site at log4js-node.github.io/log4js-node/.
Is log4js-node compatible with TypeScript?
Yes. The package ships TypeScript declarations in the types/ directory and lists them as the types entry in package.json. Importing the package as import * as log4js from "log4js" in a TypeScript project gives full type coverage without installing a separate @types package.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/log4js-node-log4js-node)