Skip to content
NPM PackageFeatured

🍬 Candy Logger v2.1.0 - The Correctness Release

Candy Logger v2.1.0 is now available. This release is not about adding flashy features. It is about making Candy Logger correct, safe, predictable, and production quality . Version…

Muhammad Sheharyar Butt

Muhammad Sheharyar Butt

Full-Stack Web & Desktop App Developer

  • 10 min read
  • 11 views
Screenshot 2026 08 08 133833

Candy Logger v2.1.0 is now available.

This release focuses on making Candy Logger correct, secure, reliable, and production-ready.

Version 2.1.0 improves serialization, security, console interception, persistence, UI behavior, accessibility, mobile support, and the underlying architecture. It also introduces a cleaner core API that allows Candy Logger to be used without rendering the UI.

What Is Candy Logger?

Candy Logger is a lightweight JavaScript and TypeScript logging library that provides a visual debugging experience directly inside your application.

Instead of relying entirely on:

console.log()
console.warn()
console.error()

Candy Logger provides a structured logging interface with:

  • 🔎 Search and filtering
  • 🏷️ Tags
  • 📊 Log levels and counters
  • 📌 Pinned entries
  • 🧩 Structured object inspection
  • 📦 JSON export
  • 🎨 Themes
  • 📱 Mobile support
  • ♿ Accessibility features
  • 🔌 Custom sinks
  • 💾 Persistent logs
  • 🛡️ CSP-safe UI
  • ⚡ Dynamic UI loading

The goal is simple:

Make application logging easier to understand without turning your project into a heavy logging framework.


Why Version 2.1.0?

The previous versions of Candy Logger focused primarily on building the logging experience.

Version 2.1.0 focuses on what happens when real applications start sending real-world JavaScript values and runtime conditions to the logger.

Circular objects.

Errors.

Maps.

Sets.

DOM nodes.

BigInts.

Symbols.

Strict Content Security Policies.

React StrictMode.

Hot Module Replacement.

Corrupted localStorage.

Touch devices.

Large log volumes.

These edge cases expose whether a developer tool is actually robust.

That's why version 2.1.0 is a correctness release.


What's New in 2.1.0

Safer Object Serialization

Logging should never break the application being debugged.

Previously, circular objects could cause a TypeError to escape into the calling code.

For example:

const circularObject = {};

circularObject.self = circularObject;

console.log(circularObject);

Candy Logger 2.1.0 safely handles circular references instead of allowing them to crash the logging operation.


Better Error Serialization

JavaScript Error objects contain valuable debugging information that isn't always enumerable.

Previously:

console.error(new Error("Something went wrong"));

could effectively render as:

{}

Version 2.1.0 properly serializes:

  • message
  • stack
  • cause
  • Custom Error properties

For example:

const error = new Error("Database connection failed", {
  cause: new Error("Connection timeout")
});

error.code = "DB_CONNECTION_FAILED";

console.error(error);

Candy Logger can now display the information developers actually need when diagnosing failures.


More JavaScript Types

The serializer has been expanded to safely handle a much wider range of JavaScript values.

Candy Logger 2.1.0 supports serialization of:

  • Map
  • Set
  • Date
  • RegExp
  • BigInt
  • Symbol
  • Functions
  • DOM nodes
  • Circular objects
  • Error objects

This means developers don't have to manually convert everything into plain JSON before logging it.


Security and XSS Protection

Security is one of the most important parts of this release.

Version 2.1.0 addresses XSS risks involving dynamically rendered values such as:

  • Object keys
  • Tag labels
  • Tag colors
  • Log levels
  • Custom action labels

For example:

console.log({
  "<img src=x onerror=alert(1)>": "test"
});

The value is treated as data rather than executable HTML.

This makes the logging interface significantly safer when handling dynamically generated or untrusted values.


Strict CSP Support

Candy Logger 2.1.0 is fully functional under a strict Content Security Policy.

The panel no longer relies on inline handlers such as:

onclick="..."

and no longer depends on:

window.__candy*

global variables.

UI interactions are handled through proper event listeners and encapsulated runtime behavior.


Idempotent Console Override

Modern development environments can execute initialization code more than once.

React StrictMode and Hot Module Replacement are common examples.

Previously, repeatedly calling:

overrideConsole();

could result in stacked panels or duplicated logs.

Version 2.1.0 makes overrideConsole() idempotent.

Calling it multiple times no longer creates additional interception layers.

overrideConsole();
overrideConsole();
overrideConsole();

The console remains correctly overridden.


Safer Console Restoration

restoreConsole() has also been improved.

It can no longer leave the browser's console permanently hijacked after restoration.

overrideConsole();

// Application code

restoreConsole();

The original console behavior is properly restored.


Accurate Log Counters

maxLogs previously caused level counters to drift upward indefinitely.

For example, even after old entries had been evicted, counters could continue increasing.

Version 2.1.0 keeps the counters synchronized with the actual core store.


Pinned Logs

Pinned logs are now exempt from normal log eviction.

If:

maxLogs: 100

is configured, pinned entries remain available even after the limit is reached.

The same behavior applies to:

clear();

Pinned entries are preserved instead of being silently removed from localStorage.


Search now matches text inside collapsed objects.

Previously, searching depended on the rendered DOM, which meant content inside collapsed objects could be missed.

Now the search operates against the underlying serialized data.

For example:

console.log({
  user: {
    profile: {
      email: "developer@example.com"
    }
  }
});

The email can be found even while the object remains collapsed.


Improved JSON Highlighting

JSON rendering has also been improved.

Version 2.1.0 correctly highlights:

  • Keys
  • Strings
  • Values

Apostrophes are also rendered correctly instead of appearing as:

&#039;

Improved Light Theme

The light theme now defines its own level badge colors.

Previously, some level badges had poor contrast, reaching approximately 1.6:1 in certain cases.

Version 2.1.0 improves the contrast and readability of the light theme.


Mobile and Touch Support

Candy Logger now provides a dedicated mobile experience.

On screens below 640px, the panel becomes a full-screen sheet.

Dragging also works with touch through pointer events, with the panel automatically clamped to the visible screen.


Accessibility Improvements

Version 2.1.0 includes an accessibility pass covering:

  • Accessible names
  • aria-pressed
  • Live regions
  • Focus rings
  • Reduced-motion support

The goal is to make the debugging interface usable with different input methods and accessibility settings.


New APIs

destroy()

Both the logger and panel now support:

destroy();

This removes:

  • DOM elements
  • Event listeners
  • Injected stylesheets

This is useful when loggers are dynamically mounted and unmounted.


captureConsole()

captureConsole() allows console output to be routed into an existing logger without replacing the entire logging architecture.

const logger = createLogger();

const dispose = captureConsole(logger);

// console.log()
// console.warn()
// console.error()

dispose();

The function returns a disposer for clean lifecycle management.


addSink()

Logs can now be piped into external systems using sinks.

logger.addSink((entry) => {
  // Send entry to your backend
});

This makes integrations with services such as:

  • Sentry
  • Custom APIs
  • Monitoring systems
  • Analytics platforms
  • Test spies

much easier.


Core Logger API

Version 2.1.0 introduces a cleaner core API:

createLogger()
attachUI()
detachUI()
showPanel()
hidePanel()
isConsoleOverridden()

This separates the logging core from the visual panel.

The logger can therefore be used without rendering the UI.


Console Format Specifiers

Candy Logger now supports common console formatting specifiers:

%s
%d
%i
%f
%o
%O
%j
%c
%%

For example:

console.log(
  "User %s has %d points",
  "Muhammad",
  100
);

This makes Candy Logger behave more naturally when capturing or replacing native console output.


Better Scrolling

The panel now uses sticky-bottom scrolling.

If you're already at the bottom, new entries keep you at the bottom.

If you've intentionally scrolled upward, new logs don't force you back down.

Instead, Candy Logger displays an:

N new

indicator.

You can then decide when to return to the newest entries.


Exported Serializer Primitives

Developers can now use Candy Logger's serialization utilities independently.

The following primitives are exported:

safeStringify
normalize
serializeError
formatArgs

This makes the serialization system useful outside the panel itself.


New Configuration Options

Version 2.1.0 introduces several configuration options:

retainArgs
persistPins
dimWhenIdle
maxDepth
maxString

These provide more control over memory usage, serialization depth, persistence, and panel behavior.

The panel is now opaque by default.

The previous dimmed behavior can be enabled using:

dimWhenIdle: true

Build Formats

Candy Logger now provides:

  • ESM
  • CJS
  • IIFE

CDN builds are also available through:

  • unpkg
  • jsDelivr

This allows Candy Logger to be used directly with a script tag:

<script src="https://unpkg.com/candy-logger"></script>

without requiring a bundler.


Testing

Version 2.1.0 includes 118 tests.

The tests cover important areas including:

  • Serialization
  • Console interception
  • Restoration
  • Persistence
  • Log limits
  • Pinned entries
  • UI behavior
  • Edge cases
  • Configuration behavior

The goal is not just to add functionality, but to make that functionality predictable.


Architecture Improvements

One of the most important changes in 2.1.0 is the separation between the logging core and the visual panel.

Core Store

These methods now read directly from the core store:

getLogs()
getStats()

They work even when no panel is attached.

For example:

const logger = createLogger();

logger.log("Hello");

console.log(logger.getLogs());
console.log(logger.getStats());

Dynamic Panel Loading

The panel is now dynamically imported.

This allows bundlers to remove the panel code from builds where the UI is never enabled.

The architecture is effectively:

Application

    ├── Logger Core

    └── Optional Panel

The visual interface is now an optional presentation layer rather than a mandatory part of the logging core.


Removed Legacy Code

Version 2.1.0 removes unnecessary legacy functionality.

Removed tableView

The tableView option has been removed because there was no alternative view.

Removed v1 Terminal UI

The old:

terminal-ui.ts

implementation from v1 has also been removed.

Candy Logger 2.x is now focused entirely on the newer architecture.


Backward Compatibility

Candy Logger 2.1.0 maintains compatibility with the important v2 APIs.

The following continue to work:

overrideConsole()
restoreConsole()
candy
CandyLogger
tagged()
getLogs()
getStats()

All v2.0 options continue to work except:

tableView

The existing:

forceUI

option is also still accepted as an alias for:

enabled

Installation

Upgrade to version 2.1.0 with:

npm install candy-logger@2.1.0

Or install the latest release:

npm install candy-logger

Getting Started

A basic setup remains simple:

import { overrideConsole } from "candy-logger";

overrideConsole({
  enabled: true
});

You can then continue using the native console API:

console.log("Application started");

console.info("User authenticated");

console.warn("Cache is getting full");

console.error(new Error("Something went wrong"));

Candy Logger handles the rest.


What's Next?

Candy Logger 2.1.0 establishes a stronger foundation for future development.

Future improvements can build on:

  • A separated logging core
  • Safer serialization
  • Extensible sinks
  • Better lifecycle management
  • Optional UI loading
  • Improved accessibility
  • Better mobile behavior
  • Stronger test coverage

The goal is to keep Candy Logger lightweight while making it increasingly useful as a developer tool.


Final Thoughts

Candy Logger 2.1.0 isn't defined by one huge feature.

Instead, it is a collection of improvements that make the entire library more reliable.

Better serialization.

Better security.

Better console interception.

Better persistence.

Better accessibility.

Better mobile behavior.

Better architecture.

And 118 tests helping make sure those improvements continue working.

That's why I consider 2.1.0 the correctness release.

🍬 Candy Logger — because debugging doesn't have to be boring.


Share this post
Muhammad Sheharyar Butt

Written by

Muhammad Sheharyar Butt

Full-Stack Web & Desktop App Developer

Full-stack developer specialising in React, Node.js and Electron, with deep experience in e-commerce automation across Shopify, WordPress, Amazon and eBay.

More about me

Keep reading

All posts

Have something you want built properly?

Tell me what you're working on and I'll come back with a clear scope, a timeline and a fixed quote.