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

@homedev/framework

v1.0.3

Published

homedev framework

Downloads

252

Readme

homedev framework

Set of classes and utilities for extending Node.js with common patterns and helpers.

Logger

constructor(options?)

Creates a logger with optional overrides for level, timestamp, and output function.

Arguments:

  • options: partial logger configuration.

Usage:

const log = new Logger({ level: 'WARN', timeStamp: true })

write(level, ...args)

Writes a log message at the given level when allowed by current threshold.

Arguments:

  • level: log level name, for example INFO or ERROR.
  • args: message parts to log.

Usage:

log.write('ERROR', 'Something failed', err)

info(...args), warn(...args), error(...args), debug(...args), verbose(...args)

Convenience methods for common log levels.

Arguments:

  • args: message parts to log.

Usage:

log.info('Server started')
log.warn('Retrying request')

StringBuilder

constructor(initial?, options?)

Builds strings efficiently with optional formatting behavior.

Arguments:

  • initial: initial content as string, list of strings, or another builder.
  • options: indentation and line formatting options.

Usage:

const sb = new StringBuilder('hello', { indentSize: 2 })

setOptions(options)

Replaces current formatting options.

Arguments:

  • options: new StringBuilder options.

Usage:

sb.setOptions({ lineSeparator: '\n', trim: true })

clear(), isEmpty(), toString()

Core buffer controls.

Arguments:

  • clear: none.
  • isEmpty: none.
  • toString: none.

Usage:

sb.clear()
sb.isEmpty()
sb.toString()

indent(), dedent(), getCurrentIndent()

Controls current indentation level used by formatted line writes.

Arguments:

  • indent: none.
  • dedent: none.
  • getCurrentIndent: none.

Usage:

sb.indent().writeLine('child').dedent()

getLines(), formatLine(line?)

Reads content as lines or formats a single line according to options.

Arguments:

  • line: optional source line.

Usage:

const line = sb.formatLine('hello')
const lines = sb.getLines()

write(...args), writeLine(...args), writeMap(items, fn)

Main writing helpers.

Arguments:

  • write: any values to append.
  • writeLine: values to append as formatted lines.
  • writeMap: items list and callback (item, index, builder).

Usage:

sb.write('A', 'B').writeLine('C')
sb.writeMap([1, 2], n => `${n}\n`)

Markdown

header(text, level?)

Writes a markdown heading and an empty line after it.

Arguments:

  • text: heading content.
  • level: heading level, normalized to 1..6.

Usage:

md.header('Overview', 2)

codeBlock(code?, language?), endCodeBlock()

Writes fenced code blocks. Fences are adjusted if code already contains backticks.

Arguments:

  • code: optional code text.
  • language: optional language id.

Usage:

md.codeBlock('const x = 1', 'ts')
md.codeBlock().writeLine('manual').endCodeBlock()

link(text, url, title?)

Writes an inline markdown link.

Arguments:

  • text: visible link text.
  • url: link target.
  • title: optional title attribute.

Usage:

md.link('Docs', '/docs', 'Open docs')

table(headers, rows)

Writes a markdown table with automatic column padding.

Arguments:

  • headers: column headers (must not be empty).
  • rows: table rows as arrays.

Usage:

md.table(['Name', 'Age'], [['Alice', '30'], ['Bob', '25']])

blockquote(text)

Writes one blockquote line per input line.

Arguments:

  • text: quote text, can be multiline.

Usage:

md.blockquote('Line 1\nLine 2')

bold(text), italic(text), code(text)

Inline text style helpers.

Arguments:

  • text: value to wrap in markdown markers.

Usage:

md.bold('Important').write(' ').italic('note').write(' ').code('x')

item(text), items(values), orderedList(items, start?)

List helpers for bullets and numbered lists.

Arguments:

  • item: single bullet text.
  • items: array of values or object map.
  • orderedList: list items and optional start index.

Usage:

md.item('One')
md.items(['A', 'B'])
md.orderedList(['First', 'Second'], 3)

horizontalRule(), image(alt, url)

Writes separators and images.

Arguments:

  • horizontalRule: none.
  • image: alt text and image URL.

Usage:

md.horizontalRule()
md.image('logo', '/img/logo.png')

strikethrough(text), highlight(text), subscript(text), superscript(text)

Additional inline formatting helpers.

Arguments:

  • text: content to format.

Usage:

md.strikethrough('old').write(' ').highlight('new')

taskList(items)

Writes GitHub-style task checklist entries.

Arguments:

  • items: list of { text, checked }.

Usage:

md.taskList([{ text: 'Ship release', checked: false }])

section(text, level?), endSection(), setSectionLevel(level)

Nested section heading workflow.

Arguments:

  • section: heading text and optional explicit level.
  • endSection: none.
  • setSectionLevel: explicit current section depth.

Usage:

md.section('Chapter')
md.section('Details')
md.endSection()

Array functions

mapAsync(callback), forEachAsync(callback)

Async iteration helpers.

Arguments:

  • callback: async callback (item, index, array).

Usage:

const names = await users.mapAsync(async u => u.name)
await users.forEachAsync(async u => save(u))

sortBy(selector, ascending?)

Returns a sorted copy using selector value comparison.

Arguments:

  • selector: function extracting sort value.
  • ascending: sort direction, default true.

Usage:

const ordered = users.sortBy(u => u.age)

unique(), uniqueBy(selector), groupBy(selector)

Deduplication and grouping helpers.

Arguments:

  • unique: none.
  • uniqueBy: key selector.
  • groupBy: key selector.

Usage:

ids.unique()
users.uniqueBy(u => u.id)
users.groupBy(u => u.role)

toObject(keySelector, valueSelector?), toObjectWithKey(key)

Converts arrays into object maps.

Arguments:

  • keySelector: key function.
  • valueSelector: optional value function.
  • key: property name used as key.

Usage:

users.toObject(u => u.id)
users.toObjectWithKey('id')

nonNullMap(callback), nonNullMapAsync(callback)

Maps and removes nullish callback outputs.

Arguments:

  • callback: mapping callback.

Usage:

const values = items.nonNullMap(i => i.optional)

findOrFail(predicate, message?, thisArg?)

Finds first match or throws an error.

Arguments:

  • predicate: match function.
  • message: optional error message.
  • thisArg: optional predicate context.

Usage:

const admin = users.findOrFail(u => u.role === 'admin', 'Admin not found')

selectFor(predicate, selector, message?, thisArg?)

Finds an item then returns selected projection.

Arguments:

  • predicate: match function.
  • selector: projection function.
  • message: optional error message.
  • thisArg: optional predicate context.

Usage:

const email = users.selectFor(u => u.id === 1, u => u.email)

createInstances(Target, ...args)

Creates class instances from array values.

Arguments:

  • Target: constructor function.
  • args: shared constructor args.

Usage:

const models = rows.createInstances(UserModel, commonConfig)

mergeAll(options?)

Merges all array objects into one output object.

Arguments:

  • options: merge conflict behavior options.

Usage:

const config = [{ a: 1 }, { b: 2 }].mergeAll()

Array.flat(value)

Static helper that flattens array input or wraps non-array values.

Arguments:

  • value: value or array.

Usage:

const result = Array.flat([1, [2, 3]])

Object functions

mapEntries(obj, callback)

Transforms object entries into a new object.

Arguments:

  • obj: source object.
  • callback: returns [newKey, newValue].

Usage:

const mapped = Object.mapEntries({ a: 1 }, ([k, v]) => [k.toUpperCase(), v * 2])

toList(obj, keyName)

Converts object map into array items and adds key field.

Arguments:

  • obj: source object.
  • keyName: property name for map key.

Usage:

const rows = Object.toList({ x: { n: 1 } }, 'id')

deepClone(obj)

Performs deep clone using structuredClone or JSON fallback.

Arguments:

  • obj: value to clone.

Usage:

const copy = Object.deepClone(original)

merge(source, target, options?)

Deep-merges source values into target object.

Arguments:

  • source: source object.
  • target: target object, modified in place.
  • options: conflict and strategy handlers.

Usage:

Object.merge(sourceConfig, targetConfig)

navigate(obj, callback)

Walks object tree and allows replace/delete/update while traversing.

Arguments:

  • obj: root object.
  • callback: visitor callback with path context.

Usage:

Object.navigate(data, ({ value }) => value)

find(from, predicate)

Returns nested values matching predicate.

Arguments:

  • from: root object.
  • predicate: match function.

Usage:

const ids = Object.find(data, ({ key }) => key === 'id')

select(from, path, options?)

Selects nested values with path expressions and options.

Arguments:

  • from: root object.
  • path: selection path.
  • options: set/default/optional behavior.

Usage:

const city = Object.select(user, 'address.city')

String functions

toPascal(), capitalize(), toCamel(), toSnake(), toKebab(), changeCase(to)

Case conversion helpers.

Arguments:

  • changeCase: to target format.

Usage:

'hello world'.toCamel()
'hello_world'.toPascal()
'sample'.changeCase('upper')

splitWithQuotes(separator?), splitNested(separator, open, close)

Split helpers that respect quoted or nested segments.

Arguments:

  • splitWithQuotes: optional separator, default comma.
  • splitNested: separator plus opening/closing delimiters.

Usage:

'a, "b, c", d'.splitWithQuotes(',')
'a(b,c),d'.splitNested(',', '(', ')')

toStringBuilder()

Converts string into StringBuilder initialized by lines.

Arguments:

  • none.

Usage:

const sb = 'line1\nline2'.toStringBuilder()

toHtmlLink(path?), toRgb(), toArgb()

Formatting helpers for links and colors.

Arguments:

  • path: optional URL for anchor.
  • toRgb: none, expects hex color string.
  • toArgb: none, expects ARGB hex color string.

Usage:

'Docs'.toHtmlLink('/docs')
'#ff0080'.toRgb()
'80ff0080'.toArgb()

single(char), remove(char), toAlphanum(), toAlpha()

String cleanup helpers.

Arguments:

  • char: character or regex fragment to collapse/remove.

Usage:

'a---b'.single('-')
'a-b-c'.remove('-')
'a!1b'.toAlphanum()

padBlock(indent, separator?, padder?), tokenize(values, tokenizer?), stripIndent()

Text block and templating helpers.

Arguments:

  • padBlock: indent size, optional separator and pad char.
  • tokenize: value map and optional token regex.
  • stripIndent: none.

Usage:

'first\nsecond'.padBlock(2)
'Hello ${name}'.tokenize({ name: 'Ada' })

File functions

exists(fileName)

Checks whether a file is readable.

Arguments:

  • fileName: file path.

Usage:

const ok = await exists('config.json')

locate(fileName, dirs?)

Resolves a file path by searching optional directories.

Arguments:

  • fileName: relative or absolute file name.
  • dirs: optional directories to check.

Usage:

const fullPath = await locate('settings.json', ['.', 'config'])

loadFormat(fileName, options?)

Reads and parses file content by format or extension matching.

Arguments:

  • fileName: file to load.
  • options: parser map, lookup dirs, or forced format.

Usage:

const data = await loadFormat('data.json')

writeFormat(filePath, content, options?)

Encodes and writes content using selected encoder.

Arguments:

  • filePath: destination path.
  • content: value to write.
  • options: encoder map and format.

Usage:

await writeFormat('out.json', { ok: true }, { format: 'json' })

globMap(pattern, options)

Runs async mapping over files that match glob pattern(s).

Arguments:

  • pattern: glob pattern or direct file path.
  • options: cwd, optional filter, and async mapper.

Usage:

const files = await globMap('**/*.ts', { cwd: '.', map: async f => f })

writeOutputs(outputs, options?), writeOutput(output, options?)

Writes one or many typed outputs with filtering support.

Arguments:

  • outputs/output: output definition(s) with name/value/type/class.
  • options: target dir, class filtering, and pre-write hook.

Usage:

await writeOutputs([{ name: 'a.json', type: 'json', value: { a: 1 } }], { targetDirectory: 'dist' })

importList(modules, options?), importGlob(patterns, options?)

Dynamically imports modules from explicit list or glob patterns.

Arguments:

  • modules/patterns: module list or glob list.
  • options: cwd, default-resolution mode, filters, fail strategy, mapper.

Usage:

const mods = await importList(['./tool.ts'])
const many = await importGlob(['**/*.ts'], { cwd: 'plugins' })

getCwd(cwd?)

Resolves effective working directory.

Arguments:

  • cwd: optional absolute or relative directory.

Usage:

const base = getCwd('config')

Global helpers

AsyncFunction

Runtime alias to async function constructor.

Usage:

const fn = new AsyncFunction('x', 'return x * 2')

defined(value, msg?)

Returns value when not null/undefined; throws otherwise.

Arguments:

  • value: value to validate.
  • msg: optional error message.

Usage:

const safe = defined(input, 'Input is required')