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

@serve.zone/nupst

v5.1.5

Published

Network UPS Shutdown Tool - Monitor SNMP-enabled UPS devices and orchestrate graceful system shutdowns during power emergencies

Readme

NUPST Migration Plan: Node.js → Deno v4.0.0

Migration Goal: Convert NUPST from Node.js to Deno with single-executable distribution Version: 3.1.2 → 4.0.0 (breaking changes) Platforms: Linux x64/ARM64, macOS x64/ARM64, Windows x64


Phase 0: Planning & Preparation

  • [x] Research Deno compilation targets and npm: specifier support
  • [x] Analyze current codebase structure and dependencies
  • [x] Define CLI command structure simplification
  • [x] Create detailed migration task list
  • [ ] Create feature branch: migration/deno-v4
  • [ ] Backup current working state with git tag: v3.1.2-pre-deno-migration

Phase 1: Dependency Migration (4-6 hours)

1.1 Analyze Current Dependencies

  • [ ] List all production dependencies from package.json
  • [ ] List all dev dependencies to be removed
    • @git.zone/tsbuild, @git.zone/tsrun, @git.zone/tstest, @push.rocks/qenv, @push.rocks/tapbundle, @types/node
  • [ ] Identify Node.js built-in module usage
    • child_process (execSync)
    • https (for version checking)
    • fs (readFileSync, writeFileSync, existsSync, mkdirSync)
    • path (join, dirname, resolve)

1.2 Create Deno Configuration

  • [ ] Create deno.json with project configuration
    {
      "name": "@serve.zone/nupst",
      "version": "4.0.0",
      "exports": "./mod.ts",
      "tasks": {
        "dev": "deno run --allow-all mod.ts",
        "compile": "deno task compile:all",
        "compile:all": "bash scripts/compile-all.sh",
        "test": "deno test --allow-all tests/",
        "check": "deno check mod.ts"
      },
      "lint": {
        "rules": {
          "tags": ["recommended"]
        }
      },
      "fmt": {
        "useTabs": false,
        "lineWidth": 100,
        "indentWidth": 2,
        "semiColons": true
      },
      "compilerOptions": {
        "lib": ["deno.window"],
        "strict": true
      },
      "imports": {
        "@std/cli": "jsr:@std/cli@^1.0.0",
        "@std/fmt": "jsr:@std/fmt@^1.0.0",
        "@std/path": "jsr:@std/path@^1.0.0"
      }
    }

1.3 Update Import Statements

  • [ ] ts/snmp/manager.ts: Change import * as snmp from 'net-snmp' to import * as snmp from "npm:[email protected]"
  • [ ] ts/cli.ts: Change import { execSync } from 'child_process' to import { execSync } from "node:child_process"
  • [ ] ts/nupst.ts: Change import * as https from 'https' to import * as https from "node:https"
  • [ ] Search for all fs imports and update to node:fs
  • [ ] Search for all path imports and update to node:path
  • [ ] Update all relative imports to use .ts extension instead of .js
    • Example: './nupst.js''./nupst.ts'

1.4 Test npm: Specifier Compatibility

  • [ ] Create test file: tests/snmp_compatibility_test.ts
  • [ ] Test SNMP v1 connection with npm:net-snmp
  • [ ] Test SNMP v2c connection with npm:net-snmp
  • [ ] Test SNMP v3 connection with npm:net-snmp
  • [ ] Verify native addon loading works in compiled binary

Phase 2: Code Structure Refactoring (3-4 hours)

2.1 Create Main Entry Point

  • [ ] Create mod.ts as main Deno entry point:
    #!/usr/bin/env -S deno run --allow-all
    
    /**
     * NUPST - UPS Shutdown Tool for Deno
     *
     * Required Permissions:
     * --allow-net: SNMP communication with UPS devices
     * --allow-read: Configuration file access (/etc/nupst/config.json)
     * --allow-write: Configuration file updates
     * --allow-run: System commands (systemctl, shutdown)
     * --allow-sys: System information (hostname, OS info)
     * --allow-env: Environment variables
     */
    
    import { NupstCli } from './ts/cli.ts';
    
    const cli = new NupstCli();
    await cli.parseAndExecute(Deno.args);

2.2 Update All Import Extensions

Files to update (change .js → .ts in imports):

  • [ ] ts/index.ts
  • [ ] ts/cli.ts (imports from ./nupst.js, ./logger.js)
  • [ ] ts/nupst.ts (imports from ./snmp/manager.js, ./daemon.js, etc.)
  • [ ] ts/daemon.ts (imports from ./snmp/manager.js, ./logger.js, ./helpers/)
  • [ ] ts/systemd.ts (imports from ./daemon.js, ./logger.js)
  • [ ] ts/cli/service-handler.ts
  • [ ] ts/cli/group-handler.ts
  • [ ] ts/cli/ups-handler.ts
  • [ ] ts/snmp/index.ts
  • [ ] ts/snmp/manager.ts (imports from ./types.js, ./oid-sets.js)
  • [ ] ts/snmp/oid-sets.ts (imports from ./types.js)
  • [ ] ts/helpers/index.ts
  • [ ] ts/logger.ts

2.3 Update process.argv References

  • [ ] ts/cli.ts: Replace process.argv with Deno.args (adjust indexing: process.argv[2] → Deno.args[0])
  • [ ] Update parseAndExecute method to work with Deno.args (0-indexed vs 2-indexed)

2.4 Update File System Operations

  • [ ] Search for fs.readFileSync() → Consider using Deno.readTextFile() or keep node:fs
  • [ ] Search for fs.writeFileSync() → Consider using Deno.writeTextFile() or keep node:fs
  • [ ] Search for fs.existsSync() → Keep node:fs or use Deno.stat
  • [ ] Search for fs.mkdirSync() → Keep node:fs or use Deno.mkdir
  • [ ] Decision: Keep node:fs for consistency or migrate to Deno APIs?

2.5 Update Path Operations

  • [ ] Verify all path.join(), path.resolve(), path.dirname() work with node:path
  • [ ] Consider using @std/path from JSR for better Deno integration

2.6 Handle __dirname and __filename

  • [ ] Find all __dirname usage
  • [ ] Replace with import.meta.dirname (Deno) or dirname(fromFileUrl(import.meta.url))
  • [ ] Find all __filename usage
  • [ ] Replace with import.meta.filename or fromFileUrl(import.meta.url)

Phase 3: CLI Command Simplification (3-4 hours)

3.1 Design New Command Structure

Current → New mapping:

OLD                          NEW
===                          ===
nupst enable                 → nupst service enable
nupst disable                → nupst service disable
nupst daemon-start           → nupst service start-daemon
nupst logs                   → nupst service logs
nupst stop                   → nupst service stop
nupst start                  → nupst service start
nupst status                 → nupst service status

nupst add                    → nupst ups add
nupst edit [id]              → nupst ups edit [id]
nupst delete <id>            → nupst ups remove <id>
nupst list                   → nupst ups list
nupst setup                  → nupst ups edit (removed alias)
nupst test                   → nupst ups test

nupst group list             → nupst group list
nupst group add              → nupst group add
nupst group edit <id>        → nupst group edit <id>
nupst group delete <id>      → nupst group remove <id>

nupst config                 → nupst config show
nupst update                 → nupst update
nupst uninstall              → nupst uninstall
nupst help                   → nupst help / nupst --help
(new)                        → nupst --version

3.2 Update CLI Parser (ts/cli.ts)

  • [ ] Refactor parseAndExecute() to handle new command structure
  • [ ] Add service subcommand handler
  • [ ] Add ups subcommand handler
  • [ ] Keep group subcommand handler (already exists, just update delete→remove)
  • [ ] Add config subcommand handler with show default
  • [ ] Add --version flag handler
  • [ ] Update help command to show new structure
  • [ ] Add command aliases: rmremove, lslist
  • [ ] Add --json flag for machine-readable output (future enhancement)

3.3 Update Command Handlers

  • [ ] ts/cli/service-handler.ts: Update method names if needed
  • [ ] ts/cli/ups-handler.ts: Rename delete()remove(), remove setup method
  • [ ] ts/cli/group-handler.ts: Rename delete()remove()

3.4 Improve Help Messages

  • [ ] Update showHelp() in ts/cli.ts with new command structure
  • [ ] Update showGroupHelp() in ts/cli.ts
  • [ ] Add showServiceHelp() method
  • [ ] Add showUpsHelp() method
  • [ ] Add showConfigHelp() method
  • [ ] Include usage examples in help text

3.5 Add Version Command

  • [ ] Read version from deno.json
  • [ ] Create --version handler in CLI
  • [ ] Display version with build info

Phase 4: Compilation & Distribution (2-3 hours)

4.1 Create Compilation Script

  • [ ] Create directory: scripts/
  • [ ] Create scripts/compile-all.sh:
    #!/bin/bash
    set -e
    
    VERSION=$(cat deno.json | jq -r '.version')
    BINARY_DIR="dist/binaries"
    
    echo "Compiling NUPST v${VERSION} for all platforms..."
    mkdir -p "$BINARY_DIR"
    
    # Linux x86_64
    echo "→ Linux x86_64..."
    deno compile --allow-all --output "$BINARY_DIR/nupst-linux-x64" \
      --target x86_64-unknown-linux-gnu mod.ts
    
    # Linux ARM64
    echo "→ Linux ARM64..."
    deno compile --allow-all --output "$BINARY_DIR/nupst-linux-arm64" \
      --target aarch64-unknown-linux-gnu mod.ts
    
    # macOS x86_64
    echo "→ macOS x86_64..."
    deno compile --allow-all --output "$BINARY_DIR/nupst-macos-x64" \
      --target x86_64-apple-darwin mod.ts
    
    # macOS ARM64
    echo "→ macOS ARM64..."
    deno compile --allow-all --output "$BINARY_DIR/nupst-macos-arm64" \
      --target aarch64-apple-darwin mod.ts
    
    # Windows x86_64
    echo "→ Windows x86_64..."
    deno compile --allow-all --output "$BINARY_DIR/nupst-windows-x64.exe" \
      --target x86_64-pc-windows-msvc mod.ts
    
    echo ""
    echo "✓ Compilation complete!"
    ls -lh "$BINARY_DIR/"
  • [ ] Make script executable: chmod +x scripts/compile-all.sh

4.2 Test Local Compilation

  • [ ] Run deno task compile to compile for all platforms
  • [ ] Verify all 5 binaries are created
  • [ ] Check binary sizes (should be reasonable, < 100MB each)
  • [ ] Test local binary on current platform: ./dist/binaries/nupst-linux-x64 --version

4.3 Update Installation Scripts

  • [ ] Update install.sh:
    • Remove Node.js download logic (lines dealing with vendor/node-*)
    • Add detection for binary download from GitHub releases
    • Simplify to download appropriate binary based on OS/arch
    • Place binary in /opt/nupst/bin/nupst
    • Create symlink: /usr/local/bin/nupst → /opt/nupst/bin/nupst
    • Update to v4.0.0 in script
  • [ ] Simplify or remove setup.sh (no longer needed without Node.js)
  • [ ] Update bin/nupst launcher:
    • Option A: Keep as simple wrapper
    • Option B: Remove and symlink directly to binary
  • [ ] Update uninstall.sh:
    • Remove vendor directory cleanup
    • Update paths to new binary location

4.4 Update Systemd Service

  • [ ] Update systemd service file path in ts/systemd.ts
  • [ ] Verify ExecStart points to correct binary location: /opt/nupst/bin/nupst daemon-start
  • [ ] Remove Node.js environment variables if any
  • [ ] Test service installation and startup

Phase 5: Testing & Validation (4-6 hours)

5.1 Create Deno Test Suite

  • [ ] Create tests/ directory (or migrate from existing test/)
  • [ ] Create tests/snmp_test.ts: Test SNMP manager functionality
  • [ ] Create tests/config_test.ts: Test configuration loading/saving
  • [ ] Create tests/cli_test.ts: Test CLI parsing and command routing
  • [ ] Create tests/daemon_test.ts: Test daemon logic
  • [ ] Remove dependency on @git.zone/tstest and @push.rocks/tapbundle
  • [ ] Use Deno's built-in test runner (Deno.test())

5.2 Unit Tests

  • [ ] Test SNMP connection with mock responses
  • [ ] Test configuration validation
  • [ ] Test UPS status parsing for different models
  • [ ] Test group logic (redundant/non-redundant modes)
  • [ ] Test threshold checking
  • [ ] Test version comparison logic

5.3 Integration Tests

  • [ ] Test CLI command parsing for all commands
  • [ ] Test config file creation and updates
  • [ ] Test UPS add/edit/remove operations
  • [ ] Test group add/edit/remove operations
  • [ ] Mock systemd operations for testing

5.4 Binary Testing

  • [ ] Test compiled binary on Linux x64
  • [ ] Test compiled binary on Linux ARM64 (if available)
  • [ ] Test compiled binary on macOS x64 (if available)
  • [ ] Test compiled binary on macOS ARM64 (if available)
  • [ ] Test compiled binary on Windows x64 (if available)
  • [ ] Verify SNMP functionality works in compiled binary
  • [ ] Verify config file operations work in compiled binary
  • [ ] Test systemd integration with compiled binary

5.5 Performance Testing

  • [ ] Measure binary size for each platform
  • [ ] Measure startup time: time ./nupst-linux-x64 --version
  • [ ] Measure memory footprint during daemon operation
  • [ ] Compare with Node.js version performance
  • [ ] Document performance metrics

5.6 Upgrade Path Testing

  • [ ] Create test with v3.x config
  • [ ] Verify v4.x can read existing config
  • [ ] Test migration from old commands to new commands
  • [ ] Verify systemd service upgrade path

Phase 6: Distribution Strategy (2-3 hours)

6.1 GitHub Actions Workflow

  • [ ] Create .github/workflows/release.yml:
    name: Release
    on:
      push:
        tags:
          - 'v*'
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: denoland/setup-deno@v1
            with:
              deno-version: v1.x
          - name: Compile binaries
            run: deno task compile
          - name: Generate checksums
            run: |
              cd dist/binaries
              sha256sum * > SHA256SUMS
          - name: Create Release
            uses: softprops/action-gh-release@v1
            with:
              files: dist/binaries/*
              generate_release_notes: true

6.2 Update package.json for npm

  • [ ] Update version to 4.0.0
  • [ ] Update description to mention Deno
  • [ ] Add postinstall script to symlink appropriate binary:
    {
      "name": "@serve.zone/nupst",
      "version": "4.0.0",
      "description": "UPS Shutdown Tool - Deno-based single executable",
      "bin": {
        "nupst": "bin/nupst-npm-wrapper.js"
      },
      "type": "module",
      "scripts": {
        "postinstall": "node bin/setup-npm-binary.js"
      },
      "files": [
        "dist/binaries/*",
        "bin/*"
      ]
    }
  • [ ] Create bin/setup-npm-binary.js to symlink correct binary
  • [ ] Create bin/nupst-npm-wrapper.js as entry point

6.3 Verify Distribution Methods

  • [ ] Test GitHub release download and installation
  • [ ] Test npm install from tarball
  • [ ] Test direct install.sh script
  • [ ] Verify all methods create working installation

Phase 7: Documentation Updates (2-3 hours)

7.1 Update README.md

  • [ ] Remove Node.js requirements section
  • [ ] Update features list (mention Deno, single executable)
  • [ ] Update installation methods:
    • Method 1: Quick install script (updated)
    • Method 2: GitHub releases (new)
    • Method 3: npm (updated with notes)
  • [ ] Update usage section with new command structure
  • [ ] Add command mapping table (v3 → v4)
  • [ ] Update platform support matrix (note: no Windows ARM)
  • [ ] Update "System Changes" section (no vendor directory)
  • [ ] Update security section (remove Node.js mentions)
  • [ ] Update uninstallation instructions

7.2 Create MIGRATION.md

  • [ ] Create detailed migration guide from v3.x to v4.x
  • [ ] List all breaking changes:
    1. CLI command structure reorganization
    2. No Node.js requirement
    3. Windows ARM not supported
    4. Installation path changes
  • [ ] Provide command mapping table
  • [ ] Explain config compatibility
  • [ ] Document upgrade procedure
  • [ ] Add rollback instructions

7.3 Update CHANGELOG.md

  • [ ] Add v4.0.0 section with all breaking changes
  • [ ] List new features (Deno, single executable)
  • [ ] List improvements (startup time, binary size)
  • [ ] List removed features (Windows ARM, setup command alias)
  • [ ] Migration guide reference

7.4 Update Help Text

  • [ ] Ensure all help commands show new structure
  • [ ] Add examples for common operations
  • [ ] Include migration notes in help output

Phase 8: Cleanup & Finalization (1 hour)

8.1 Remove Obsolete Files

  • [ ] Delete vendor/ directory (Node.js binaries)
  • [ ] Delete dist/ directory (old compiled JS)
  • [ ] Delete dist_ts/ directory (old compiled TS)
  • [ ] Delete node_modules/ directory
  • [ ] Remove or update tsconfig.json (decide if needed for npm compatibility)
  • [ ] Remove setup.sh if no longer needed
  • [ ] Remove old test files in test/ if migrated to tests/
  • [ ] Delete pnpm-lock.yaml

8.2 Update Git Configuration

  • [ ] Update .gitignore:
    # Deno
    .deno/
    deno.lock
    
    # Compiled binaries
    dist/binaries/
    
    # Old Node.js artifacts (to be removed)
    node_modules/
    vendor/
    dist/
    dist_ts/
    pnpm-lock.yaml
  • [ ] Add deno.lock to version control
  • [ ] Create .denoignore if needed

8.3 Final Validation

  • [ ] Run deno check mod.ts - verify no type errors
  • [ ] Run deno lint - verify code quality
  • [ ] Run deno fmt --check - verify formatting
  • [ ] Run deno task test - verify all tests pass
  • [ ] Run deno task compile - verify all binaries compile
  • [ ] Test each binary manually

8.4 Prepare for Release

  • [ ] Create git tag: v4.0.0
  • [ ] Push to main branch
  • [ ] Push tags to trigger release workflow
  • [ ] Verify GitHub Actions workflow succeeds
  • [ ] Verify binaries are attached to release
  • [ ] Test installation from GitHub release
  • [ ] Publish to npm: npm publish
  • [ ] Test npm installation

Rollback Strategy

If critical issues are discovered:

  • [ ] Keep v3.1.2 tag available for rollback
  • [ ] Create v3-stable branch for continued v3 maintenance
  • [ ] Update install.sh to offer v3/v4 choice
  • [ ] Document known issues in GitHub Issues
  • [ ] Provide downgrade instructions in docs

Success Criteria Checklist

  • [ ] ✅ All 5 platform binaries compile successfully
  • [ ] ✅ Binary sizes are reasonable (< 100MB per platform)
  • [ ] ✅ Startup time < 2 seconds
  • [ ] ✅ SNMP v1/v2c/v3 functionality verified on real UPS device
  • [ ] ✅ All CLI commands work with new structure
  • [ ] ✅ Config file compatibility maintained
  • [ ] ✅ Systemd integration works on Linux
  • [ ] ✅ Installation scripts work on fresh systems
  • [ ] ✅ npm package still installable and functional
  • [ ] ✅ All tests pass
  • [ ] ✅ Documentation is complete and accurate
  • [ ] ✅ GitHub release created with binaries
  • [ ] ✅ Migration guide tested by following it step-by-step

Timeline

  • Phase 0: 1 hour ✓ (in progress)
  • Phase 1: 4-6 hours
  • Phase 2: 3-4 hours
  • Phase 3: 3-4 hours
  • Phase 4: 2-3 hours
  • Phase 5: 4-6 hours
  • Phase 6: 2-3 hours
  • Phase 7: 2-3 hours
  • Phase 8: 1 hour

Total Estimate: 22-31 hours


Notes & Decisions

Key Decisions Made:

  1. ✅ Use npm:net-snmp (no pure Deno SNMP library available)
  2. ✅ Major version bump to 4.0.0 (breaking changes)
  3. ✅ CLI reorganization with subcommands
  4. ✅ Keep npm publishing alongside binary distribution
  5. ✅ 5 platform targets (Windows ARM not supported by Deno yet)

Open Questions:

  • [ ] Should we keep tsconfig.json for npm package compatibility?
  • [ ] Should we fully migrate to Deno APIs (Deno.readFile) or keep node:fs?
  • [ ] Should we remove the bin/nupst wrapper or keep it?
  • [ ] Should setup.sh be completely removed or kept for dependencies?

Risk Areas:

  • ⚠️ SNMP native addon compatibility in compiled binaries (HIGH PRIORITY TO TEST)
  • ⚠️ Systemd integration with new binary structure
  • ⚠️ Config migration from v3 to v4
  • ⚠️ npm package installation with embedded binaries