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

im.console

v0.3.2

Published

import.meta.console — console.* with file:line:col baked into every call

Readme

im.console

import.meta.console.* — every console call gets the source file's basename plus the call-site line:col baked in at build time.

import.meta.console.log("hello", user);
import.meta.console.warn("cache miss for", key);
import.meta.console.error("boom", error);

becomes

[auth.ts:12:3] hello { id: 1 }
[cache.ts:48:5] cache miss for users/42
[handler.ts:7:5] boom Error: boom at ...

import.meta.console mirrors the full Console interface (log/warn/error/info/debug/trace/table/dir/group/groupEnd/ time/timeEnd/timeLog/count/countReset/assert/clear). It is also directly callable as a shorthand for .log:

import.meta.console("quick log"); // → console.log('[file.ts:1:1] quick log')

You can also capture a reference and call it later. The location prefix is baked in where the reference is taken, not where it's called:

const logger = import.meta.console.warn; // location captured here
const c = import.meta.console; // ditto — `c.error(...)` uses this line
arr.forEach(import.meta.console.log);

import.meta.console.* is non-optional by design — the babel plugin must be active for any file that uses it. Code without the plugin running will throw TypeError: Cannot read property 'log' of undefined.

Install

npm install --save-dev im.console

Use

Add the Babel plugin:

// babel.config.js
module.exports = {
	presets: ["babel-preset-expo"],
	plugins: ["im.console/plugin"],
};

That's it. The plugin rewrites every import.meta.console.<method>(...) into a call to the small im.console/runtime module, which forwards to console.<method> with the location prefix prepended.

Options

[
	"im.console/plugin",
	{
		// 'esm' (default) or 'cjs' — controls how the runtime is imported.
		module: "esm",
		// Override the runtime specifier (rarely needed).
		runtimeSpecifier: "im.console/runtime",
	},
];

Bun

If you run your code directly with Bun (bun file.ts), you don't need a separate Babel build step — im.console/bun is a Bun plugin that applies the same transform on the fly, as each module is loaded.

The recommended wiring is bunfig.toml, which makes a plain bun file.ts (no --preload flag) Just Work, including for every file file.ts imports:

# bunfig.toml
preload = ["im.console/bun/preload"]

im.console/bun/preload registers the plugin with default options. For custom options, write your own preload module instead:

// im-console-preload.ts
import { imConsolePlugin } from "im.console/bun";

Bun.plugin(
	imConsolePlugin({
		// Override the runtime specifier (rarely needed).
		runtimeSpecifier: "im.console/runtime",
		// Restrict which files are transformed (default: all JS/TS source files).
		filter: /\.[cm]?[jt]sx?$/,
	}),
);
# bunfig.toml
preload = ["./im-console-preload.ts"]

You can also pass it on the command line instead of via bunfig.toml:

bun --preload ./im-console-preload.ts file.ts

Either way the transform reaches the whole module graph — the entry file and every file it imports — because Bun runs preload plugins' onLoad hooks for every module it loads.

TypeScript

im.console ships ambient typings that augment ImportMeta with the console property:

/// <reference types="im.console/types" />

Reference it once anywhere in your project (e.g. in a globals.d.ts or your entry file). import.meta.console.log(...) will then type-check everywhere.

Why a build-time transform?

Reading the call-site line/column at runtime requires throwing an Error and parsing its stack on every call. Baking it in at load time keeps the rewritten code small and the runtime hot path trivial.

License

MIT.