npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

web-log-viewer

v0.2.2

Published

A web based log viewer # Installation

Downloads

23

Readme

A web based log viewer

Installation

npm install --global web-log-viewer

How it works

In the server component:

  1. reads one line of text from stdin
  2. transforms the line of text into JSON using a parser
  3. sends that JSON data to the web client via websocket

In the web client:

  1. transforms the received JSON data into another JSON structure using a formatter
  2. displays the formatted data in an HTML table
  3. allow the user to see the full contents of the parsed message

Usage

Display the contents of a file. Use the default parser, which parses each line of text with json5

    cat file.log | web-log-viewer

Then go to http://localhost:8000. You can use tail instead of cat to follow changes made to the file.

Pipe the stdout of a command. Use a custom parser to transform lines of text to JSON.

cmd.sh | web-log-viewer --parser my-custom-parser.js --port 8080

Then go to http://localhost:8080

Parser

The parser runs in the server component, and transform a single line of text into a JSON object that will be sent to the web client. For example, a parser could be used to transform logs produced by log4j into JSON.

The default parser simply tries to parse data with json5:

import json5 from 'json5'
/**
 * Default parser implementation, that transforms a string (usually a single
 * line of text coming in from **stdin**) into a JSON object containing the data
 * present in a log message
 */
module.exports = (rawMessage: string) => {
  try {
    return json5.parse(rawMessage)
  } catch (err) {
    const msg = { message: rawMessage }
    return msg
  }
}

Formatter

Formatters run in the web client; their purpose is to select which fields of the JSON object should be displayed by the web client. Note that a single server can have several web clients (i.e., browser tabs), each with their own formatter.

A formatter consists of an object, where each field consists of a function. Each function is executed with the JSON object sent by the server component, and must return the value that will be displayed to the user.

For example, the following formatter will display three fields:

const formatDate = d => new Date(d).toISOString();

({
    '#': (log, seq) => seq,
    message: log => log.message,
    level: log => log.meta.logLevel,
    time: log => formatDate(log.timestamp),
})`

Errors that occur in these formatter functions are ignored, and the return will return empty string instead.

NOTE: this uses eval!

TODO (or, stuff that will never get done)

  • should accept a transformer function that maps a single line from stdin into a list of RawMessages. Some examples would be:
    • 1:1 mapping (the default) would not do any transformations. For when we have a log file with JSON (or JSON5) format
    • 1:1 mapping, transforming a textual (e.g., log4j) log file into JSON
    • 1:n mapping, transforming a JSON file, wich potentially included lots of information in arrays, into a list of RawMessages
  • the client (svelte) should display the status of the connection with the server
  • the client (svelte) should be able to restore the connection with the server when it is available again
  • security when accessing the logs?
  • grouping rows (e.g., group all messages belonging to the same request)
  • filtering by timestamp
  • log line color
  • possibility to return a primary and secondary value for each column; return a color/css; return a width for the column
  • use https://developer.mozilla.org/en-US/docs/Mozilla/Tech/XPCOM/Language_Bindings/Components.utils.Sandbox?