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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@brianbuie/node-kit

v0.13.0

Published

Basic tools for Node.js projects

Downloads

1,613

Readme

NPM Version

Node Kit

Basic tools for Node.js projects

Installing

npm add @brianbuie/node-kit
import { Fetcher, Log } from '@brianbuie/node-kit';

Extending Config

tsconfig.json

{
  "extends": "./node_modules/@brianbuie/node-kit/tsconfig.json"
}

prettier.config.ts

export * from './node_modules/@brianbuie/node-kit/prettier.config.ts';

Or make changes:

import baseConfig from './node_modules/@brianbuie/node-kit/prettier.config.ts';

const config = {
  ...baseConfig,
  printWidth: 80,
};

export default config;

API

Links: API, Classes, Functions, Types, Variables

Classes

| | | --- | | Cache | | Dir | | Fetcher | | File | | FileType | | FileTypeCsv | | FileTypeJson | | FileTypeNdjson | | Format | | Log | | TypeWriter |

Links: API, Classes, Functions, Types, Variables


Class: Cache

Save data to a local file with an expiration. Fresh/stale data is returned with a flag for if it's fresh or not, so stale data can still be used if needed.

export class Cache<T> {
    file;
    ttl;
    constructor(key: string, ttl: number | Duration, initialData?: T) 
    write(data: T) 
    read(): [
        T | undefined,
        boolean
    ] 
}

Links: API, Classes, Functions, Types, Variables


Class: Dir

Reference to a specific directory with methods to create and list files.

export class Dir {
    #inputPath;
    #resolved?: string;
    isTemp;
    constructor(inputPath: string, options: DirOptions = {}) 
    get path() 
    dir(subPath: string, options: DirOptions = { temp: this.isTemp }) 
    tempDir(subPath: string) 
    sanitize(filename: string) 
    filepath(base: string) 
    file(base: string) 
    get files() 
    clear() 
}

See also: DirOptions, temp

Constructor

constructor(inputPath: string, options: DirOptions = {}) 

See also: DirOptions

Argument Details

  • path
    • can be relative to workspace or absolute

Method dir

Create a new Dir inside the current Dir

dir(subPath: string, options: DirOptions = { temp: this.isTemp }) 

See also: DirOptions, temp

Argument Details

  • subPath
    • joined with parent Dir's path to make new Dir
  • options
    • include { temp: true } to enable the .clear() method. If current Dir is temporary, child directories will also be temporary.

Example

const folder = new Dir('example');
// folder.path = '/path/to/cwd/example'
const child = folder.dir('path/to/dir');
// child.path = '/path/to/cwd/example/path/to/dir'

Method filepath

filepath(base: string) 

Argument Details

  • base
    • The file base (name and extension)

Example

const folder = new Dir('example');
const filepath = folder.resolve('file.json');
// 'example/file.json'

Method tempDir

Creates a new temp directory inside current Dir

tempDir(subPath: string) 

Argument Details

  • subPath
    • joined with parent Dir's path to make new TempDir

Links: API, Classes, Functions, Types, Variables


Class: Fetcher

Fetcher provides a quick way to set up a basic API connection with options applied to every request. Includes basic methods for requesting and parsing responses

export class Fetcher {
    defaultOptions;
    constructor(opts: FetchOptions = {}) 
    buildUrl(route: Route, opts: FetchOptions = {}): [
        URL,
        string
    ] 
    buildHeaders(route: Route, opts: FetchOptions = {}) 
    buildRequest(route: Route, opts: FetchOptions = {}): [
        Request,
        FetchOptions,
        string
    ] 
    async fetch(route: Route, opts: FetchOptions = {}): Promise<[
        Response,
        Request
    ]> 
    async fetchText(route: Route, opts: FetchOptions = {}): Promise<[
        string,
        Response,
        Request
    ]> 
    async fetchJson<T>(route: Route, opts: FetchOptions = {}): Promise<[
        T,
        Response,
        Request
    ]> 
}

See also: FetchOptions, Route

Method buildHeaders

Merges options to get headers. Useful when extending the Fetcher class to add custom auth.

buildHeaders(route: Route, opts: FetchOptions = {}) 

See also: FetchOptions, Route

Method buildRequest

Builds request, merging defaultOptions and provided options. Includes Abort signal for timeout

buildRequest(route: Route, opts: FetchOptions = {}): [
    Request,
    FetchOptions,
    string
] 

See also: FetchOptions, Route

Method buildUrl

Build URL with URLSearchParams if query is provided. Also returns domain, to help with cookies

buildUrl(route: Route, opts: FetchOptions = {}): [
    URL,
    string
] 

See also: FetchOptions, Route

Method fetch

Builds and performs the request, merging provided options with defaultOptions. If opts.data is provided, method is updated to POST, content-type json, data is stringified in the body. Retries on local or network error, with increasing backoff.

async fetch(route: Route, opts: FetchOptions = {}): Promise<[
    Response,
    Request
]> 

See also: FetchOptions, Route

Links: API, Classes, Functions, Types, Variables


Class: File

Represents a file on the file system. If the file doesn't exist, it is created the first time it is written to.

export class File {
    path;
    root;
    dir;
    base;
    name;
    ext;
    type;
    constructor(filepath: string) 
    get exists() 
    get stats(): Partial<fs.Stats> 
    delete() 
    read() 
    lines() 
    get readStream() 
    get writeStream() 
    write(contents: string | ReadableStream) 
    append(lines: string | string[]) 
    json<T>(contents?: T) 
    static get json() 
    ndjson<T extends object>(lines?: T | T[]) 
    static get ndjson() 
    async csv<T extends object>(rows?: T[], keys?: (keyof T)[]) 
    static get csv() 
}

Method append

creates file if it doesn't exist, appends string or array of strings as new lines. File always ends with '\n', so contents don't need to be read before appending

append(lines: string | string[]) 

Method csv

async csv<T extends object>(rows?: T[], keys?: (keyof T)[]) 

Returns

FileTypeCsv adaptor for current File, adds '.csv' extension if not present.

Example

const file = await new File('a').csv([{ col: 'val' }, { col: 'val2' }]); // FileTypeCsv<{ col: string; }>
await file.write([ { col2: 'val2' } ]); // ❌ 'col2' doesn't exist on type { col: string; }
await file.write({ col: 'val' }); // ✅ Writes one row
await file.write([{ col: 'val2' }, { col: 'val3' }]); // ✅ Writes multiple rows

Method delete

Deletes the file if it exists

delete() 

Method json

json<T>(contents?: T) 

Returns

FileTypeJson adaptor for current File, adds '.json' extension if not present.

Examples

const file = new File('./data').json({ key: 'val' }); // FileTypeJson<{ key: string; }>
console.log(file.path) // '/path/to/cwd/data.json'
file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }
const file = new File('./data').json<object>({ key: 'val' }); // FileTypeJson<object>
file.write({ something: 'else' }) // ✅ data is typed as object

Method lines

lines() 

Returns

lines as strings, removes trailing '\n'

Method ndjson

ndjson<T extends object>(lines?: T | T[]) 

Returns

FileTypeNdjson adaptor for current File, adds '.ndjson' extension if not present.

Method read

read() 

Returns

the contents of the file as a string, or undefined if the file doesn't exist

Links: API, Classes, Functions, Types, Variables


Class: FileType

A generic file adaptor, extended by specific file type implementations

export class FileType {
    file;
    constructor(filepath: string, contents?: string) 
    get path() 
    get root() 
    get dir() 
    get base() 
    get name() 
    get ext() 
    get type() 
    get exists() 
    get stats() 
    delete() 
    get readStream() 
    get writeStream() 
}

Links: API, Classes, Functions, Types, Variables


Class: FileTypeCsv

Comma separated values (.csv). Input rows as objects, keys are used as column headers

export class FileTypeCsv<Row extends object> extends FileType {
    constructor(filepath: string) 
    async write(rows: Row[], keys?: Key<Row>[]) 
    #parseVal(val: string) 
    async read() 
}

See also: FileType

Links: API, Classes, Functions, Types, Variables


Class: FileTypeJson

A .json file that maintains data type when reading/writing.

⚠️ This is mildly unsafe, important/foreign json files should be validated at runtime!

Examples

const file = new FileTypeJson('./data', { key: 'val' }); // FileTypeJson<{ key: string; }>
console.log(file.path) // '/path/to/cwd/data.json'
file.write({ something: 'else' }) // ❌ property 'something' doesn't exist on type { key: string; }
const file = new FileTypeJson<object>('./data', { key: 'val' }); // FileTypeJson<object>
file.write({ something: 'else' }) // ✅ data is typed as object
export class FileTypeJson<T> extends FileType {
    constructor(filepath: string, contents?: T) 
    read() 
    write(contents: T) 
}

See also: FileType

Links: API, Classes, Functions, Types, Variables


Class: FileTypeNdjson

New-line delimited json file (.ndjson)

export class FileTypeNdjson<T extends object> extends FileType {
    constructor(filepath: string, lines?: T | T[]) 
    append(lines: T | T[]) 
    lines() 
}

See also: FileType

Links: API, Classes, Functions, Types, Variables


Class: Format

Helpers for formatting dates, times, and numbers as strings

export class Format {
    static date(formatStr: "iso" | "ymd" | "ymd-hm" | "ymd-hms" | "h:m:s" | string = "iso", d: DateArg<Date> = new Date()) 
    static round(n: number, places = 0) 
    static plural(amount: number, singular: string, multiple?: string) 
    static ms(ms: number, style?: "digital") 
    static bytes(b: number) 
}

Method date

date-fns format() with some shortcuts

static date(formatStr: "iso" | "ymd" | "ymd-hm" | "ymd-hms" | "h:m:s" | string = "iso", d: DateArg<Date> = new Date()) 

Argument Details

  • formatStr
    • the format to use
  • date
    • the date to format, default new Date()

Example

Format.date('iso') // '2026-04-08T13:56:45Z'
Format.date('ymd') // '20260408'
Format.date('ymd-hm') // '20260408-1356'
Format.date('ymd-hms') // '20260408-135645'
Format.date('h:m:s') // '13:56:45'

Method ms

Make millisecond durations actually readable (eg "123ms", "3.56s", "1m 34s", "3h 24m", "2d 4h")

static ms(ms: number, style?: "digital") 

Argument Details

  • ms
    • milliseconds
  • style
    • 'digital' to output as 'HH:MM:SS'

Method round

Round a number to a specific set of places

static round(n: number, places = 0) 

Links: API, Classes, Functions, Types, Variables


Class: Log

export class Log {
    static getStack() 
    static #toGcloud(entry: Entry) 
    static #toConsole(entry: Entry, color: ChalkInstance) 
    static #log({ severity, color }: Options, ...input: unknown[]) 
    static prepare(...input: unknown[]): {
        message?: string;
        details: unknown[];
    } 
    static alert(...input: unknown[]) 
    static error(...input: unknown[]) 
    static warn(...input: unknown[]) 
    static notice(...input: unknown[]) 
    static info(...input: unknown[]) 
    static debug(...input: unknown[]) 
}

Method

Gcloud parses JSON in stdout

static #toGcloud(entry: Entry) 

Method

Includes colors and better inspection for logging during dev

static #toConsole(entry: Entry, color: ChalkInstance) 

Method alert

Events that require action or attention immediately

static alert(...input: unknown[]) 

Method debug

Debug or trace information

static debug(...input: unknown[]) 

Method error

Events that cause problems

static error(...input: unknown[]) 

Method info

Routine information, such as ongoing status or performance

static info(...input: unknown[]) 

Method notice

Normal but significant events, such as start up, shut down, or a configuration change

static notice(...input: unknown[]) 

Method prepare

Handle first argument being a string or an object with a 'message' prop

static prepare(...input: unknown[]): {
    message?: string;
    details: unknown[];
} 

Method warn

Events that might cause problems

static warn(...input: unknown[]) 

Links: API, Classes, Functions, Types, Variables


Class: TypeWriter

export class TypeWriter {
    moduleName;
    input = qt.jsonInputForTargetLanguage("typescript");
    outDir;
    qtSettings;
    constructor(moduleName: string, settings: {
        outDir?: string;
    } & Partial<qt.Options> = {}) 
    async addMember(name: string, _samples: any[]) 
    async toString() 
    async toFile() 
}

Method toString

function toString() { [native code] }

async toString() 

Links: API, Classes, Functions, Types, Variables


Functions

| | | --- | | snapshot | | timeout |

Links: API, Classes, Functions, Types, Variables


Function: snapshot

Allows special objects (Error, Headers, Set) to be included in JSON.stringify output. Functions are removed

export function snapshot(i: unknown, max = 50, depth = 0): any 

Links: API, Classes, Functions, Types, Variables


Function: timeout

export async function timeout(ms: number) 

Links: API, Classes, Functions, Types, Variables


Types

| | | --- | | DirOptions | | FetchOptions | | Query | | Route |

Links: API, Classes, Functions, Types, Variables


Type: DirOptions

export type DirOptions = {
    temp?: boolean;
}

See also: temp

Links: API, Classes, Functions, Types, Variables


Type: FetchOptions

export type FetchOptions = RequestInit & {
    base?: string;
    query?: Query;
    headers?: Record<string, string>;
    data?: any;
    timeout?: number;
    retries?: number;
    retryDelay?: number;
}

See also: Query, timeout

Links: API, Classes, Functions, Types, Variables


Type: Query

export type Query = Record<string, QueryVal | QueryVal[]>

Links: API, Classes, Functions, Types, Variables


Type: Route

export type Route = string | URL

Links: API, Classes, Functions, Types, Variables


Variables

| | | --- | | cwd | | temp |

Links: API, Classes, Functions, Types, Variables


Variable: cwd

cwd = new Dir("./")

See also: Dir

Links: API, Classes, Functions, Types, Variables


Variable: temp

temp = cwd.tempDir(".temp")

See also: cwd

Links: API, Classes, Functions, Types, Variables