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

@worktif/unix

v0.1.42

Published

A TypeScript-based Unix shell automation library for command-line operations, scripting, and terminal management with comprehensive CLI integration

Readme

@worktif/unix

npm version Node Support TypeScript License

TypeScript-first Unix automation and CLI orchestration toolkit for Node.js. It provides a strongly-typed process runner, composable pipelines, environment validation, and a modular CLI framework suitable for production automation in enterprise systems.

  • Minimal runtime, tree-shakeable
  • Predictable process lifecycles with typed states
  • Structured logging, DI-friendly architecture
  • Works well in CI/CD, containers, and developer machines

Overview

@worktif/unix is a low-level but ergonomic utility designed to standardize and harden shell/process automation in TypeScript projects. It abstracts common pitfalls of child processes (timeouts, signals, exit handling, environment composition), provides typed state machines for multi-step jobs, and exposes a small but powerful API for building CLI modules.

Unix package exists to:

  • Eliminate ad-hoc shell scripts and brittle process chains
  • Provide typed, reusable orchestration primitives
  • Unify logging/observability for automation flows
  • Enable modular CLIs with predictable argument handling

Typical targets include: build systems, asset pipelines, deployment hooks, code generation workflows, and platform automation tasks in financial, cloud, and distributed systems.


Installation

npm install @worktif/unix
# or
yarn add @worktif/unix
# or
pnpm add @worktif/unix

Key Features

  • Type-safe process orchestration
    • Run multi-step jobs with explicit states, signal handling, and structured messaging
    • Pluggable handlers for success/failure transitions
  • Composable CLI modules
    • Define commands/flags declaratively; consistent parsing patterns
    • Extend via class inheritance with minimal boilerplate
  • Production-grade logging
    • Structured logger with consistent formatting for local and CI
    • Log level controls (including debug) and stage-aware behavior
  • Environment validation
    • zod-based schemas for environment typing/validation
  • DI-ready bundle
    • Container integration for controlled lifecycle and extensibility
  • Build tool compatibility
    • Works with esbuild, tsc, webpack pipelines
  • Minimal footprint
    • No heavy runtime dependencies; designed for tree shaking

Requirements:

Usage

Below examples demonstrate typical patterns. Adjust to your environment.

Example 1: Run a single command with a custom handler

import { UnixModule } from '@worktif/unix';

type State = { workdir?: string };

const runner = new UnixModule<State>({
  argv: process.argv,
  unixInstance: {}, // your stateful instance if needed
  defaults: {
    handler: async (code, signal, state) => {
      // on each step close: merge and return state
      return state?.common ?? {};
    },
    logs: { type: 'local', serviceName: 'example:runner' },
  },
});

await runner.run<State>(
  [
    {
      definition: () => ({
        command: 'node',
        args: ['-v'],
        options: { stdio: 'inherit' },
      }),
      signal: () => ({
        message: { succeeded: 'Node printed version.', failed: 'Node failed.' },
        handler: async () => ({ workdir: process.cwd() }),
      }),
    },
  ],
  {
    state: { common: {}, steps: {} },
    handler: async (_code, _signal, state) => state?.common ?? {},
  },
);

Example 2: Multi-step pipeline with environment overrides

import { UnixModule } from '@worktif/unix';

type BuildState = { buildDir?: string };

const build = new UnixModule<BuildState>({
  argv: process.argv,
  unixInstance: {},
  defaults: {
    handler: async (_c, _s, state) => state?.common ?? {},
    logs: { type: 'local', serviceName: 'example:build' },
  },
});

await build.run<BuildState>(
  [
    {
      definition: (state) => ({
        command: 'mkdir',
        args: ['-p', state.common.buildDir!],
        options: { stdio: 'inherit' },
      }),
      signal: () => ({
        message: { succeeded: 'Build dir created.', failed: 'Build dir create failed.' },
        handler: async () => ({}),
      }),
    },
    {
      definition: (state) => ({
        command: 'bash',
        args: ['-lc', `echo "BUILDING" > ${state.common.buildDir}/artifact.txt`],
        options: {
          stdio: 'inherit',
          env: { ...process.env, NODE_ENV: 'production' },
        },
      }),
      signal: () => ({
        message: { succeeded: 'Artifact generated.', failed: 'Artifact failed.' },
        handler: async () => ({}),
      }),
    },
  ],
  {
    state: { common: { buildDir: './out/dist' }, steps: {} },
  },
);

Example 3: Define CLI flags and use structured parsing

import { UnixModule } from '@worktif/unix';
import type { UnixModuleCommandArgv } from '@worktif/unix';

type DeployState = { bucket?: string };

class DeployModule extends UnixModule<DeployState> {
  constructor(argv: string[]) {
    super({
      argv,
      unixInstance: {},
      defaults: {
        handler: async (_c, _s, state) => state?.common ?? {},
        logs: { type: 'local', serviceName: 'example:deploy' },
      },
      cmdArgv: {
        deploy: {
          text: 'deploy', simple: true, argv: {
            bucket: { text: 'bucket', double: true },
          }
        },
      } as unknown as UnixModuleCommandArgv<any>,
    });

    this.setup({
      argv,
      unixInstance: this['unixInstance'],
      defaults: this['defaults'],
      cmdArgv: this['cmdArgv'],
    });
  }

  public async deploy() {
    await this.run<DeployState>(
      [
        {
          definition: (state) => ({
            command: 'echo',
            args: [`Sync to s3://${state.common.bucket}`],
            options: { stdio: 'inherit' },
          }),
          signal: () => ({
            message: { succeeded: 'Synced.', failed: 'Sync failed.' },
            handler: async () => ({}),
          }),
        },
      ],
      {
        state: { common: {}, steps: {} },
        handler: async (_c, _s, state) => state?.common ?? {},
      },
    );
  }
}

// Usage: node app.js deploy --bucket my-bucket
new DeployModule(process.argv).watch({
  defaults: { handler: async (_c, _s, state) => state?.common ?? {}, logs: { type: 'local' } },
});

API Reference

Type signatures are simplified for readability; refer to generated typings for exact definitions.

  • UnixModule<State, Defaults>

    • constructor(options: UnixModuleOptions<State, Defaults>)
    • run(processes, initState): Promise<UnixProcessState<State>>
      • processes: Array<{ definition(state) => UnixChildProcessFnOptions; signal(state) => UnixChildProcessOptions<State>; exit?: boolean }>
      • initState: { state: { common: T; steps: Record<string, T> }, handler?: UnixChildProcessHandler<State> }
    • runCommand(process, state, index): Promise<UnixProcessState<State>>
    • watch(options): void
    • setSuppliers({ logs }): void
  • Types

    • UnixChildProcessFnOptions
      • command: string
      • args?: (string | undefined)[]
      • options?: SpawnOptions
      • description?: string
    • UnixChildProcessHandler<State> = (code, signal, state?) => State | Promise<State>
    • UnixChildProcessOptions<State>
      • handler: UnixChildProcessHandler<State>
      • message?: { succeeded?: string; failed?: string }
    • UnixProcessState<State>
      • common: State & Record<string, any>
      • steps: Record<string, State & Record<string, any>>
    • UnixModuleOptions<State, Defaults>
      • argv: string[]
      • unixInstance: State
      • defaults: { handler: UnixChildProcessHandler<State>; logs: { type: keyof LoggerCliFormatter; serviceName?: string } } & Partial<Defaults>
      • cmdArgv?: UnixModuleCommandArgv<any>
    • UnixModuleCommandArgv<T>
      • Record<string, { text: string; simple?: boolean; double?: boolean; argv?: UnixModuleCommandArgv<any> }>
  • Environment

    • EnvConfigUnix
      • Validates env via zod schema; extend to enforce required variables

Notes:

  • Logging uses a structured logger with stage-aware formatting.
  • Signals are mapped to human-readable messages; failures can terminate based on step configuration.

Use Cases

  • CI/CD pipelines
    • Deterministic, typed build and deployment steps with robust logging
  • Secure batch jobs
    • Run multi-step data processing with explicit failure handlers
  • Internal developer tooling
    • Replace shell scripts with maintainable TypeScript modules
  • Cloud build/deploy
    • Orchestrate compilers, bundlers, and cloud CLIs consistently
  • Monorepo automation
    • Standardized hooks to compile, verify, and publish packages

Design Principles

  • Functional composability
    • Steps are pure definitions that return command + signals; handlers return next state
  • Explicit state
    • State travels through steps; no hidden globals
  • Fail-fast with clear semantics
    • Each step declares success/failure messages and termination behavior
  • Low latency and minimal overhead
    • Uses Node child_process directly; avoids heavy abstractions
  • Type safety and IDE-first
    • Strong typing across public APIs; rich IntelliSense
  • Environment hygiene
    • Explicit env passing; easy to validate/lock via zod

Installation and Tooling

Commands (common project scripts):

  • Build: npm run build
  • Generate docs: npm run docs
  • Types only: npm run types
  • Publish: npm run publish:npm

Best Practices

  • Always define messages and handlers for each step to keep logs actionable
  • Keep env minimal and explicit per step
  • Prefer double-dash flags for machine execution; single for human ergonomics
  • Use watch() when exposing CLI methods; verify method existence at startup
  • Validate environment in process bootstrap via EnvConfigUnix

Performance

  • No runtime parsing frameworks; thin abstractions over spawn()
  • Suitable for high-throughput CI jobs and containerized environments
  • Minimal logging overhead; configurable log level for debug traces

Contributing

This section is intended for external publishers responsible for releasing the package to npm. Follow the sequence precisely to ensure auditability, semantic versioning integrity, and a clean release trail.

  • Authenticate to the scoped registry
    • npm login --scope=@worktif
    • If you encounter a TLS/registry error, set the registry explicitly:
      • npm config set registry https://registry.npmjs.org/
  • Complete your enhancement
    • Implement and locally validate your changes (types, build, docs as applicable).
  • Open a Pull Request (PR)
    • Submit your changes for review.
    • Await approval before proceeding.
  • Merge the PR
    • After approval, merge into main using your standard merge policy.
  • Synchronize your local main
    • git checkout main
    • git pull to ensure you’re up to date.
  • Prepare a release branch
    • Create a branch using the release template:
      • releases/v[your.semantic.version-[pre+[meta]]]-next-release-description
  • Bump the version
    • Update the package version according to SemVer (major/minor/patch).
  • Commit the version bump to the release branch
    • Commit only the version change (and any generated artifacts if required by your policy).
  • Push the release branch
    • Push the branch to the remote to trigger any CI gates.
  • Open a Release PR
    • Create a PR from the release branch to main.
    • Await approval and required checks.
  • Merge the Release PR
    • Merge into main after approvals and passing checks.
  • Final synchronization
    • Pull the latest changes from main locally.
  • Validate the version in package.json
    • Ensure the version reflects the intended release.
  • Publish
    • If the version was not increased (npm will reject):
      • Bump the version, commit, and then run yarn run publish:npm.
    • If the version has been increased and publishing fails unexpectedly:
      • Contact the maintainer at [email protected] with context (command output, Node/npm versions, CI logs).

Successful publish output resembles:

+ @worktif/unix@[your.semantic.version-[pre+[meta]]]
✨  Done in 28.81s.

Security:

  • Do not commit secrets; rely on environment variables or secret managers
  • Report vulnerabilities privately via the issue tracker’s security channel

License

This project is licensed under the Elastic License 2.0.

  • See LICENSE for the full license text.
  • See THIRD_PARTY_LICENSES.txt for third-party attributions and license texts.

Maintainers / Contact