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

tablogger

v0.1.7

Published

Universal logging function — tablog() works on frontend, backend, any language

Readme

tablogger

One function. Every language. One terminal.

tablog() is a drop-in replacement for console.log / print() that routes all logs — frontend, backend, any framework — to a single unified terminal. Run npx tablogger once and see everything in one place: colored source labels, network request tracking, log levels, split view, and a full HTTP API for querying your logs programmatically.

npx tablogger
[React]    button clicked (×3)
[React]    out  GET  /api/users              200     22ms   1.2kB
[FastAPI]  in   GET  /api/users              200     18ms   1.2kB  <> React
[FastAPI]  fetching users from db                                   main.py:42
[FastAPI]  returning 3 users                                        main.py:45

npm license


Claude Code integration

When you run npx tablogger, it automatically writes a live API reference into your project's CLAUDE.md. Claude Code reads this on every prompt — so Claude and its agents can query your logs, errors, traces, and slow requests directly as part of debugging, without any extra setup.

You:     "why is /api/users slow?"
Claude:  [curls localhost:4242/slow]
         [curls localhost:4242/trace?url=/api/users]
         "The FastAPI handler is taking 1.2s — tablog shows it's the db query on main.py:38"

When you Ctrl+C tablogger, the section is removed and CLAUDE.md is restored.


Installation

JavaScript / TypeScript

npm install tablogger

Python

pip install tablog

Quick start

1. Start the terminal

npx tablogger

2. Add to your JS app

import { tablog } from 'tablogger'

tablog('user logged in')
tablog('query result:', { rows: 42 })

3. Add to your Python app

from tablog import tablog

tablog('server started')
tablog('query result:', {'rows': 42})

Everything streams to the same terminal, labeled by source.


Features

Unified terminal for every service

All logs from React, Express, FastAPI, Flask, or any Node/Python service appear in one place with colored [Source] labels — no tab-switching.

Network request tracking

Frontend outgoing requests and backend incoming requests are captured automatically and shown in a compact line:

[React]    out  GET  /api/users   200   22ms   1.2kB
[FastAPI]  in   GET  /api/users   200   18ms         <> React

Status codes are color-coded (green/cyan/yellow/red) and slow requests (>500ms) are highlighted in red.

Request correlation

When a React fetch() and a FastAPI handler serve the same request, tablogger links them with <> React — no headers injected, no CORS issues. Matched by METHOD + path within a 3-second window.

Caller file + line (Python)

Every Python tablog() call shows the file and line number it was called from:

[FastAPI]  fetching users from db    main.py:38
[FastAPI]  returning 3 users         main.py:41

Log levels

tablog('all good')                        # default
tablog('cache miss rate high', level='warn')   # yellow
tablog('payment failed', level='error')        # red ●

Split view

/split 2

Shows two services side-by-side in the terminal. Use Tab to switch focus, arrow keys to scroll each column independently.

┌── React ─────────────────┬── FastAPI ────────────────┐
│ button clicked (×1)      │ fetching users from db    │
│ out GET /api/users  200  │ in  GET /api/users  200   │
│ button clicked (×2)      │ returning 3 users         │
└──────────────────────────┴───────────────────────────┘

HTTP log API

Query your live log stream from any tool — curl, LLM, CI script:

curl localhost:4242/logs             # all recent logs
curl localhost:4242/errors           # errors + 5xx only
curl localhost:4242/slow?ms=200      # requests over 200ms
curl localhost:4242/search?q=userId  # full-text search
curl localhost:4242/trace?url=/api/users   # full request trace
curl localhost:4242/sources          # per-source health
curl localhost:4242/timeline?since=5m
curl localhost:4242/repeat?min=3     # repeated messages

Add ?format=text to any endpoint for plain-text output (no ANSI codes).

RAG / LLM pipeline visibility

from tablog.langchain import TablogCallbackHandler

handler = TablogCallbackHandler()
[RAGApp]  retrieve  "what is the refund policy?"  5 results  top=0.91  38ms
[RAGApp]  rerank    10→3 results  12ms
[RAGApp]  prompt    2100 tokens  3 chunks
[RAGApp]  generate  gpt-4o  1240ms  2100→187 tokens

Query quality issues via the API:

curl localhost:4242/rag/quality   # low scores, truncated context, slow generation
curl localhost:4242/rag/slow      # slowest pipeline steps

Session export

/export

Saves the full session to tablog-YYYYMMDD-HHMMSS.json (structured) and .log (human-readable, ANSI stripped).


Usage

JavaScript / TypeScript

import { tablog } from 'tablogger'

tablog('user logged in')
tablog('query result:', { rows: 42 })

React / browser

import { tablog, init } from 'tablogger'

// Call once at app entry point
init({ source: 'React', network: true })

tablog('component mounted')

network: true intercepts all fetch and XHR calls automatically.

Express / Node.js

import { tablog, expressMiddleware } from 'tablogger'

app.use(expressMiddleware())   // captures all incoming requests

app.get('/api/users', (req, res) => {
  tablog('fetching users')
  res.json({ users })
})

Python

from tablog import tablog

tablog('server started')
tablog('query result:', {'rows': 42})

FastAPI

from tablog import tablog
from tablog.middleware import TablogMiddleware

app.add_middleware(TablogMiddleware, source='FastAPI')

@app.get('/api/users')
async def get_users():
    tablog('fetching users')
    return {'users': users}

Flask

from tablog.middleware import TablogFlaskMiddleware

TablogFlaskMiddleware(app)

LangChain

from tablog.langchain import TablogCallbackHandler

handler = TablogCallbackHandler(source='MyRAGApp')
chain = RetrievalQA.from_chain_type(llm=llm, callbacks=[handler])

CLI commands

Start the server:

npx tablogger

| Command | Description | |---------|-------------| | /tab 1 | Focus on service 1 only | | /tab 2 | Focus on service 2 only | | /tab all | Show all sources | | /split 2 | Side-by-side split view | | /split off | Exit split view | | /change | Interactive filter menu (toggle sources, log/network) | | /copy | Copy recent logs to clipboard | | /export | Save session to .json + .log |


How it works

┌─────────────┐    tablog()     ┌──────────────────────┐
│  React app  │ ──────────────► │                      │
│  (browser)  │   WebSocket     │  tablogger terminal  │
└─────────────┘                 │  ws://localhost:4242 │
                                │  http://localhost:4242│
┌─────────────┐    tablog()     │                      │
│  FastAPI    │ ──────────────► │  [React]   click     │
│  (Python)   │   WebSocket     │  [FastAPI] query     │
└─────────────┘                 └──────────────────────┘
  • npx tablogger starts a WebSocket + HTTP server on port 4242
  • Every tablog() call sends a JSON message over WebSocket
  • The CLI renders messages with colored [Source] labels
  • Network middleware captures HTTP request/response metadata on both sides
  • Frontend out requests are correlated with backend in responses

Configuration

tablog.config.json is auto-generated on first run (gitignored):

{
  "services": [
    { "name": "Vite",    "port": 5173, "role": "frontend" },
    { "name": "FastAPI", "port": 8000, "role": "backend"  }
  ]
}

Delete it and re-run npx tablogger to re-detect services.

Environment variables

| Variable | Default | Description | |----------|---------|-------------| | TABLOG_PORT | 4242 | WebSocket + HTTP server port | | TABLOG_SOURCE | auto-detected | Override source label |


License

MIT