# @soundboks/timbergeist

> Development fork of fullstack-build/tslog for convenience internally. Use at your own peril.

Latest version **2.0.4** (published 2025-08-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install @soundboks/timbergeist
pnpm add @soundboks/timbergeist
yarn add @soundboks/timbergeist
bun add @soundboks/timbergeist
```

## Health

**Score 45/100 (D)** — status: stable.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 2.0.4 |
| Published | 2025-08-30 |
| First published | 2023-09-29 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Node | >=18 |
| Dependencies | 1 |
| Unpacked size | 106.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | SOUNDBOKS |
| Maintainers | dabs |

## Links

- npm: https://www.npmjs.com/package/@soundboks/timbergeist
- Repository: https://github.com/soundboks/timbergeist
- npm.io page: https://npm.io/package/@soundboks/timbergeist

## Dependencies (1)

- [node-inspect-extracted](https://npm.io/package/node-inspect-extracted.md) ^2.0.2

## Recent versions

- 2.0.4 (latest) — 2025-08-30
- 2.0.3 — 2024-06-05
- 2.0.2 — 2024-05-29
- 2.0.1 — 2024-04-03
- 2.0.1-rc.0 — 2024-03-18
- 1.0.0 — 2023-09-29

## README

# Timbergeist: A flexible typescript logging framework

[![CI](https://github.com/SOUNDBOKS/timbergeist/actions/workflows/ci.yml/badge.svg)](https://github.com/SOUNDBOKS/timbergeist/actions/workflows/ci.yml)

## Features

🪶 Lightweight (1 runtime dependency)  
🏗 Universal: Works in Browsers and Node.js  
👮‍️ Fully typed even with custom Metadata  
🗃 Structured logging - JSON-first with built in pretty print transforms  
🦸 Plugable transports and transformers  
🤓 Stack trace and pretty errors  
👨‍👧‍👦 Child-logging hierarchies with proper feed-through  

## Design Rationale

### Child Loggers and Log Propagation


### Log Object Format

In Timbergeist logs are represented by a collection of javascript objects. There is no concept of a format strings or log id etc. Timbergeist is built to be flexible enough that these features can be built on top in a straight forward way.  
  
Once serialised, the object structure could look something like this:
```json
{
    "0": { "foo": 0, "bar": { "cee": 5 }},
    "1": "Hello logs!",
    "_meta": {
        "__tgLogFormatVersion": 1,
        "logLevelId": 3,
        "logLevelName": "INFO",
        ...
    }
}
```


## Usage

### Quickstart

```ts
import { Logger } from "@soundboks/timbergeist"

const RootLogger = new Logger()

RootLogger.info("Hello World")
```

### Custom Transports with different logs

In this example we submit JSON logs to a HTTP endpoint and still pretty print logs to the console. We also make sure to submit all log levels via HTTP, but only print level 3 or higher to the console to avoid clutter.

```ts
import { ConsoleSink, Logger, PrettyPrinterTransport } from "@soundboks/timbergeist";

const LOG_LEVEL_INFO = 3;
const LOG_LEVEL_DEBUG = 2;

// our "hidden" logger which is actually responsible for printing
const _RootLogger = new Logger(
	{
		minLevel: process.env["NODE_ENV"] === "production" ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG,
	},
	[
		new PrettyPrinterTransport(ConsoleSink, {
			prettyLogTemplate: "{{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} {{name}} ",
		}),
	]
);

// our exported Root Logger, which has a lower minLevel than our hidden logger
export const RootLogger = _RootLogger.getSubLogger({
	minLevel: 0,
});

RootLogger.attachTransport({
	transport(logArgs, meta) {
        const message = {
            ...logArgs,
            _meta: meta,
        }

        // In a real application you should use a batching mechanism of some sort
        fetch("https://api.foobar.com/logs/intake", {
            Body: JSON.stringify(message)
        })
    }
});
```


### Reconstructing string logs from JSON log objects

```ts
import { ConsoleSink, PrettyPrinterTransport } from "@soundboks/tslog"

const printer = new PrettyPrinterTransport(ConsoleSink, {
    prettyLogTemplate: "{{hh}}:{{MM}}:{{ss}}:{{ms}} {{logLevelName}} {{name}} ",
});

const log = MY_LOGS[0] // one log object in timbergeist format
const collectedArgs: unknown[] = []
for (let i = 0; Object.keys(log).includes(i.toString()); i++) {
    collectedArgs.push(log[i])
}

printer.transport(collectedArgs, log._meta)
```





### Differences from Tslog

- Masking as a feature has been removed entirely

## Acknowledgements

Timbergeist started out as a internal fork of [Tslog](https://github.com/fullstack-build/tslog).

---
_Source: https://npm.io/package/@soundboks/timbergeist · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
