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

@stackline/lockfile

v1.0.6

Published

Maintained compatibility-first file locking with observable asynchronous unlock failures

Readme

@stackline/lockfile

Compatibility-first filesystem lock files for CommonJS, with asynchronous unlock failures made observable.

This is an independent Stackline continuation of lockfile. It is not affiliated with or endorsed by Isaac Z. Schlueter, npm, the original maintainers, or the upstream project.

Install

For new code, install and import the scoped package directly:

npm install @stackline/[email protected]
var lockfile = require('@stackline/lockfile')

To keep an existing require('lockfile') unchanged, install the scoped package under the historical dependency key:

npm install lockfile@npm:@stackline/[email protected]

The equivalent manifest entry is:

{
  "dependencies": {
    "lockfile": "npm:@stackline/[email protected]"
  }
}

Quick start

var lockfile = require('@stackline/lockfile')
var path = 'work.lock'

lockfile.lock(path, { wait: 2000, stale: 30000 }, function (lockError) {
  if (lockError) throw lockError

  // Perform the work protected by this cooperative lock.

  lockfile.unlock(path, function (unlockError) {
    if (unlockError) throw unlockError
  })
})

Always inspect the unlock callback when cleanup matters. There is no Promise API: omitting the optional callback also omits the place where an unlink error can be observed.

CommonJS API

The runtime preserves the six-method API from [email protected]:

  • lock(path, [options], callback) acquires a lock asynchronously and calls callback(error); success has no value.
  • lockSync(path, [options]) acquires a lock or throws; success returns undefined.
  • unlock(path, [callback]) removes a lock asynchronously. Success and a missing lock both call callback() with no error. Other unlink errors are passed through unchanged.
  • unlockSync(path) makes a best-effort removal, suppresses every unlink error, and returns undefined.
  • check(path, [options], callback) calls callback(error, isLocked).
  • checkSync(path, [options]) returns a boolean or throws.

The mutable lockfile.filetime property defaults to ctime on POSIX and mtime on Windows and selects the stat timestamp used for stale checks.

Options

  • wait: milliseconds that asynchronous lock may keep polling before it returns the original contention error.
  • pollPeriod: milliseconds between polls while waiting; default 100.
  • stale: age in milliseconds after which a lock may be taken over.
  • retries: additional acquisition attempts for lock and lockSync.
  • retryWait: delay in milliseconds between asynchronous retries.

lockSync rejects wait and retryWait because it cannot sleep between attempts. checkSync rejects wait. As in the upstream implementation, supplied option objects are mutable bookkeeping inputs; avoid sharing one object between independent attempts.

The bounded unlock correction

Upstream issue npm/lockfile#18 identified the error boundary. In [email protected], asynchronous unlock discarded every fs.unlink error and always reported success.

@stackline/[email protected] changes only that branch:

  • ENOENT still means already unlocked and remains a successful no-op;
  • successful unlink still settles as callback() with undefined;
  • a non-ENOENT unlink failure such as EACCES, EPERM, or an I/O error is delivered as the original error, exactly once; and
  • synchronous unlockSync remains best-effort and suppresses unlink errors.

Acquisition, checking, retry, wait, stale, callback, on-disk, and process-exit behavior otherwise remain compatible with the published 1.0.4 artifact.

TypeScript and runtime support

First-party declarations model the callback-based CommonJS API, optional arguments, options, mutable filetime, and actual undefined success values. They are additive: the package does not introduce Promise methods, an ESM runtime, or a second implementation.

The supported runtime is Node.js >=14.17. Development and release tooling may require a newer Node.js version than consumers do.

Filesystem boundary

This package creates a zero-byte file with exclusive wx access. It is a cooperative coordination primitive, not an authorization or security boundary. Correctness depends on every participant using the same path and on the filesystem providing sufficiently atomic exclusive-create, link, unlink, and metadata behavior.

Network and distributed filesystems can weaken visibility and timestamp assumptions through attribute caches, clock differences, or coarse timestamp resolution. In particular, validate the intended mount and workload before using stale takeover on NFS or across hosts. A stale threshold that is too low can remove a live lock. Abrupt termination can leave a lock despite best-effort signal-exit cleanup.

The zero-byte format has no owner, PID, heartbeat, fencing token, or embedded stale policy. Consequently, the conflicting-threshold problem described in npm/lockfile#30 is not fixed. If you need leases, heartbeats, ownership metadata, or compromise detection, evaluate a protocol such as proper-lockfile; it is not a drop-in replacement.

More documentation