@ashulab/universal-logger
v0.1.0
Published
Isomorphic logger for Node.js and the browser — log levels, scoped loggers, structured server output and provider-agnostic error reporting, with zero config.
Downloads
43
Maintainers
Readme
universal-logger
Isomorphic logger for Node.js and the browser. It auto-detects the execution context and adjusts behavior — structured object logs on the server, formatted strings on the client — with a single, consistent API and no configuration required.
- 🌐 Universal: same import works on server and client (import-safe even
when
processis not defined in the browser). - 🎚️ Log levels:
debug,info,warn,errorbehind a single min-level threshold. - 🏷️ Scoped loggers: prefix every log with a module/service name.
- 🧱 Structured server output: JSON in production, readable objects in dev.
- 🪝 Provider-agnostic error reporting: wire any sink — Sentry, Datadog, a custom endpoint.
- 📦 ESM-only, zero runtime dependencies.
Install
npm install universal-loggerRequires Node.js >= 18. ESM only — use
import, notrequire.
Usage
import { logInfo, logError, createScopedLogger } from 'universal-logger';
logInfo('Server started', { port: 3000 });
try {
await fetchData();
} catch (err) {
logError('Failed to fetch data', err, { url: '/api/data' });
}
const log = createScopedLogger('AuthService');
log.debug('Checking token');
log.info('User authenticated');Behavior by environment
| | Server (Node.js) | Client (browser) |
|---|---|---|
| Format | Structured object / JSON | Formatted string |
| Default min level | debug in dev, warn in prod | debug in dev, warn in prod |
| Prefix | none | [App] |
A single min-level threshold governs what is logged, with the same model on
server and client: in development (NODE_ENV=development) everything from
debug up; in production only warn and error. Override it anytime via
configureUniversalLogger({ minLevel }) or the LOG_LEVEL env var.
On the server, dev mode prints readable objects; otherwise it emits one-line JSON suitable for log collectors.
Configuration
import { configureUniversalLogger, LogLevel } from 'universal-logger';
configureUniversalLogger({
enabled: true,
minLevel: LogLevel.INFO,
prefix: '[MyApp]',
});Environment variables
| Variable | Effect |
|---|---|
| LOG_LEVEL | Sets the default min level (debug | info | warn | error). Read on the server; on the client set the level via configureUniversalLogger. |
| NODE_ENV=development | When LOG_LEVEL is unset, lowers the default to debug and switches server output to readable objects. |
Error reporting (provider-agnostic)
logError forwards exceptions to a reporter of your choosing — Sentry,
Datadog, Rollbar, a custom endpoint, anything — on both server and client.
Only configureUniversalLogger({ enabled: false }) stops it.
The reporter receives the original error untouched (or a synthetic Error when
logError is called without one) plus { message, context }, and is
responsible for shaping it for its provider. Register it once at startup:
import * as Sentry from '@sentry/node';
import { setErrorReporter } from 'universal-logger';
setErrorReporter((error, { message, context }) => {
Sentry.captureException(error instanceof Error ? error : new Error(message), {
extra: { message, ...context },
});
});Any other provider follows the same shape:
setErrorReporter((error, { message, context }) => {
myMonitoring.report({ error, message, ...context });
});API
| Export | Description |
|---|---|
| logDebug(message, context?) | Debug-level log |
| logInfo(message, context?) | Info-level log |
| logWarn(message, context?) | Warning-level log |
| logError(message, error?, context?) | Error-level log; forwards to the error reporter |
| createScopedLogger(scope) | Returns { debug, info, warn, error } prefixed with [scope] |
| configureUniversalLogger(config) | Override enabled / minLevel / prefix |
| setErrorReporter(fn) | Register a provider-agnostic error reporter |
| LogLevel | Enum: DEBUG, INFO, WARN, ERROR |
Scripts
npm run build # bundle to dist/ (ESM + .d.ts) with tsup
npm run dev # build in watch mode
npm run typecheck # tsc --noEmit
npm test # build + run the node:test suiteLicense
MIT © Diego Ghersi
