New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

@cp949/console-feed

Package Overview
Dependencies
Maintainers
1
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@cp949/console-feed

A React component that displays console logs from the current page, an iframe or transported across a server

latest
Source
npmnpm
Version
3.7.4
Version published
Weekly downloads
52
-13.33%
Maintainers
1
Weekly downloads
 
Created
Source

console-feed

한국어 | English

A React component that captures and displays browser console output in a user interface. Supports React 18 and 19.

This is a fork of samdenty/console-feed v3.6.0 with security vulnerability fixes.

Current prepared release: 3.7.2

Installation

npm install @cp949/console-feed

Package info: https://www.npmjs.com/package/@cp949/console-feed

Import Paths

The package root keeps the existing public API for compatibility:

import { Console, Hook, Decode, Unhook } from '@cp949/console-feed'
import type { Message, HookedConsole, Methods } from '@cp949/console-feed'

Non-UI utilities can also be imported from stable subpaths:

import Hook from '@cp949/console-feed/hook'
import Unhook from '@cp949/console-feed/unhook'
import { Decode, Encode } from '@cp949/console-feed/transform'

Chrome 75 Library Artifacts

The library artifacts target Chrome 75. The package neither injects global polyfills nor requires consumers to install core-js.

pnpm --filter @cp949/console-feed check:chrome75 is a static audit of the built package output. node fixtures/chrome75-consumer/scripts/build-packed.mjs checks an installed tarball in a standalone consumer. Run the exact-browser smoke on Linux with Docker:

bash scripts/test-chrome75.sh

The recorded exact smoke uses Docker on Linux and Node 24 with Chromium/HeadlessChrome 75.0.3770.90; the packed consumer completed capture, decode, render, restoration, and style checks, with no fixture or CDP errors. The historical image downloads its snapshot over HTTPS and verifies the pinned Chromium deb SHA-1; trusted=yes applies only to that snapshot source. Podman and Node 22 have no equivalent execution record. This smoke verifies only the computed style checks in the fixture; broader CSS behavior, other browser engines, and other operating systems remain unverified.

Changes

전체 변경 이력은 CHANGELOG.md를 참조하세요. 아래는 최근 주요 변경의 요약입니다.

3.7.2

  • Patch release. Fixes a low-severity esbuild vulnerability (GHSA-g7r4-m6w7-qqqr) left unresolved by prior dependency updates, plus routine dependency bumps (dompurify, linkify-*, testing libraries). No public API change. See CHANGELOG.md for details.

3.7.1

  • Patch release. Library code (dist/) is identical to 3.7.0 — fixes the test:compat matrix and updates the README. See CHANGELOG.md for details.

3.7.0

  • @emotion/react, @emotion/styled, react-inspector moved to peerDependencies — consumers must install these packages explicitly.
  • TypeScript strict mode enabled — tsconfig.json consolidated to "strict": true. HookedConsole.feed is now an optional property (feed?); runtime behavior unchanged but consumers compiling under strict may need an optional guard when accessing console.feed directly.
  • react-inline-center dependency removed — replaced by inline flex styles at the single call site.

3.6.8 — Build / Distribution

  • Dual ESM + CJS build via tsdown (replaces the previous tsc-only CJS build)
  • exports map now branches on import / require for the root and every public subpath (./component, ./hook, ./unhook, ./transform)
  • Default-only subpaths (./hook, ./unhook, ./component) are emitted so that require('@cp949/console-feed/hook') and import Hook from '@cp949/console-feed/hook' both resolve to the function directly — fixes Next/Webpack interop where Hook was being received as { default: fn }

Earlier — Security Vulnerability Fixes

  • react-inspector 9.0.0 upgrade: removed @babel/runtime vulnerabilities
  • Jest → Vitest migration: resolved 22 dependency chain vulnerabilities
  • Prototype pollution defense: __proto__, constructor, prototype key filtering
  • DOM sanitization: DOMPurify applied without server-side DOM dependencies
  • Serialization depth limits added

Current Stack

  • TypeScript ^6.0.3
  • React 18, 19 support
  • Node 20+ baseline
  • Vitest ^5.0.1

Features

  • Styled console entries (color substitution, clickable links)
  • Renders DOM nodes, tables, various console methods
  • Serialization (functions, circular structures, DOM references)
  • Filtering and search
  • Error stack trace display
  • Performance measurement (console.time/timeEnd support)
  • Dark/light theme support

Basic Usage

Function component (Hooks):

import React, { useState, useEffect } from 'react'
import { Console, Hook, Decode, Unhook } from '@cp949/console-feed'
import type { Message } from '@cp949/console-feed'

const LogsContainer = () => {
  const [logs, setLogs] = useState<Message[]>([])

  useEffect(() => {
    const hookedConsole = Hook(
      window.console,
      (encoded, message) => {
        // When encode is true: encoded is a serialized message, so Decode is required
        // When encode is false: encoded is a parsed message, but using Decode is safe
        const decoded = Decode(encoded)
        const logMessage: Message = {
          ...decoded,
          id: `log-${Date.now()}-${Math.random()}`,
          data: decoded.data || [],
        }
        setLogs((prevLogs) => [...prevLogs, logMessage])
      },
      true, // encode: true - serialization for network transfer
      100, // limit: 100 - serialization depth limit
    )

    // Cleanup: Unhook when component unmounts
    return () => {
      Unhook(hookedConsole)
    }
  }, [])

  return <Console logs={logs} variant="dark" />
}

API

Console Component

A React component that displays log messages.

Props:

  • logs: Array of log messages (Message[]) - Required
  • variant?: Theme ("dark" | "light", default: "dark")
  • styles?: Custom style object
  • filter?: Method filter array (Methods[]) - Display only specified methods
  • searchKeywords?: Search keyword string - Regex search in log content
  • logFilter?: Log filtering function - Custom filtering logic when used with searchKeywords
  • logGrouping?: Enable log grouping (default: true) - Group identical logs and display with amount
  • linkifyOptions?: linkifyjs options object - URL link handling options
  • components?: Component override object - Replace with custom components

Hook Function

Wraps window.console or a console-like object to capture logs.

Hook(
  console: Console,
  callback: (encoded: Message, message: Payload) => void,
  encode?: boolean,  // Default: true
  limit?: number     // Default: 100 (serialization depth limit)
): HookedConsole

Parameters:

  • console: Console object to hook
  • callback: Callback function called when a log is captured
    • encoded: Log message (first argument)
      • When encode is true: Serialized message (suitable for network transfer/storage)
      • When encode is false: Parsed message (not serialized, for use in the same memory space)
    • message: Parsed message (second argument, always non-serialized parsed result)
  • encode: Whether to serialize logs (default: true)
    • true: Serialize parsed messages for network transfer or localStorage storage
    • false: Use parsed messages without serialization (more efficient when used in the same memory space)
  • limit: Serialization depth limit (default: 100, only applies when encode is true)

Return Value:

  • HookedConsole: Hooked Console object (can be passed to Unhook)

Unhook Function

Restores a console wrapped by Hook to its original state. Must be called when the component unmounts.

Unhook(hookedConsole: HookedConsole): boolean

Parameters:

  • hookedConsole: Console object wrapped by Hook

Return Value:

  • boolean: Success status (true: success, false: failure)

Encode / Decode Functions

Used when transmitting logs across network boundaries.

Encode<T>(data: any, limit?: number): T
Decode(data: any): Message

Encode:

  • Converts log objects into JSON-serializable format
  • Safely converts functions, circular references, DOM nodes, etc.
  • limit: Serialization depth limit (default: 100)
  • Return Value: Flat object structure that can be serialized to JSON
    • Complex types (functions, DOM nodes, etc.) from the original object are converted with special type markers
    • Can be safely serialized with JSON.stringify()
    • Suitable for network transfer, localStorage storage, etc.

Decode:

  • Deserializes serialized logs into Message objects
  • Returns a complete log object including the method property
  • Important:
    • When encode is true: The first argument (encoded) of the callback is a serialized message, so Decode must be called
    • When encode is false: The first argument (encoded) of the callback is a parsed message, but calling Decode is recommended for safe usage

Usage Example:

import { Encode, Decode } from '@cp949/console-feed'

// 1. Create log message
const logMessage = {
  method: 'log' as const,
  data: [
    'Hello World',
    { name: 'console-feed', version: '3.7.2' },
    [1, 2, 3],
  ],
  timestamp: new Date().toISOString(),
}

// 2. Encode: Serialize for network transfer
const encoded = Encode(logMessage, 100)
// encoded is an object that can be serialized with JSON.stringify()
// Example: { method: 'log', data: [...], timestamp: '...' }

// 3. Simulate network transfer (convert to JSON)
const jsonString = JSON.stringify(encoded)
// Can be stored in localStorage or sent over network

// 4. Parse JSON on receiving side
const received = JSON.parse(jsonString)

// 5. Decode: Deserialize to restore original form
const decoded = Decode(received)
// decoded is a complete log object of type Message
// { method: 'log', data: [...], timestamp: '...' }

// 6. Pass to Console component
<Console logs={[decoded]} variant="dark" />

Real-world Usage Scenario:

// Send log to server
const sendLogToServer = (log: Message) => {
  const encoded = Encode(log, 100)
  fetch('/api/logs', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(encoded), // Can be safely serialized
  })
}

// Display logs received from server
const receiveLogFromServer = async () => {
  const response = await fetch('/api/logs')
  const encodedLogs = await response.json()

  const decodedLogs = encodedLogs.map((encoded: any) => Decode(encoded))
  setLogs(decodedLogs)
}

Capturing Logs from iframe

You can display console methods like console.log(), console.error() executed inside an iframe in the main window's console-feed.

Simple Method:

After the iframe loads, hook the iframe's contentWindow.console.

import React, { useState, useEffect, useRef } from 'react'
import { Console, Hook, Decode, Unhook } from '@cp949/console-feed'
import type { Message, HookedConsole } from '@cp949/console-feed'

const IframeLogsContainer = () => {
  const [logs, setLogs] = useState<Message[]>([])
  const iframeRef = useRef<HTMLIFrameElement | null>(null)

  useEffect(() => {
    const iframe = iframeRef.current
    if (!iframe) return

    let hookedConsole: HookedConsole | null = null

    // Wait for iframe to load
    const handleLoad = () => {
      if (!iframe.contentWindow) {
        console.error('iframe contentWindow is not available')
        return
      }

      // Hook iframe's console
      const iframeConsole = iframe.contentWindow.console
      hookedConsole = Hook(
        iframeConsole,
        (encoded, message) => {
          // encode is true, so use Decode to decode the log (required!)
          const decoded = Decode(encoded)
          const logMessage: Message = {
            ...decoded,
            id: `log-${Date.now()}-${Math.random()}`,
            data: decoded.data || [],
          }
          setLogs((prevLogs) => [...prevLogs, logMessage])
        },
        true, // encode: true
        100, // limit: 100
      )
    }

    iframe.addEventListener('load', handleLoad)

    // Cleanup: Clean up when component unmounts
    return () => {
      if (hookedConsole && iframe.contentWindow) {
        Unhook(hookedConsole)
      }
      iframe.removeEventListener('load', handleLoad)
    }
  }, [])

  return (
    <div>
      <iframe ref={iframeRef} src="./your-iframe.html" />
      <Console logs={logs} variant="dark" />
    </div>
  )
}

Notes:

  • Console must be hooked after the iframe loads (load event)
  • The iframe and main window must be same-origin to access contentWindow.console
  • Must call Unhook when the component unmounts to clean up

Development

Project Structure

console-feed/
├── apps/
│   └── demo/              # Demo app (Vite + React)
├── packages/
│   └── console-feed/      # Library core
├── turbo.json             # Turborepo configuration
├── pnpm-workspace.yaml    # pnpm workspace setup
└── package.json           # Root workspace

Development Requirements

  • Node ^22.18.0 (CI baseline)
  • pnpm 11.27.1

Development Commands

# Install dependencies
pnpm install

# Run development server for entire workspace
pnpm dev

# Build entire workspace
pnpm build

# Test entire workspace
pnpm test

# Run specific package only
pnpm --filter @cp949/console-feed build    # Build library
pnpm --filter demo dev                      # Run demo app only
pnpm --filter @cp949/console-feed test     # Test library

React 18/19 Compatibility Testing

# Test both React 18 and 19
pnpm test:compat

# Test React 18 only
pnpm test:react18

# Test React 19 only
pnpm test:react19

Script: packages/console-feed/scripts/test-react-compat.sh

Release

Only the library package (@cp949/console-feed) is published to npm.

Before releasing, update and commit CHANGELOG.md; release-it requires a clean working tree.

# Starts the interactive release flow from the repository root.
pnpm release-it

The flow updates only this package's package.json, runs prepublishOnly (build, test, test:dist), publishes to npm, then interactively confirms the release commit, v<version> tag, and push. Use the prompts to choose the version and approve each external action.

License

MIT

Keywords

devtools

FAQs

Package last updated on 16 Oct 2026

Related posts