VibeTunnel NPM Package Distribution
This document explains the npm package build process, native module handling, and prebuild system for VibeTunnel.Overview
VibeTunnel is distributed as an npm package that includes:- Full web server with terminal sharing capabilities
- Native modules for terminal (PTY) and authentication (PAM) support
- Cross-platform prebuilt binaries to avoid requiring build tools
- Command-line tools (
vibetunnel
andvt
)
Package Structure
Native Modules
VibeTunnel requires two native modules:1. node-pty (Terminal Support)
- Purpose: Provides pseudo-terminal (PTY) functionality
- Components:
pty.node
: Main Node.js addon for terminal operationsspawn-helper
: macOS-only C helper binary for process spawning
- Platforms: All (macOS, Linux)
- Dependencies: None (vendored implementation)
2. authenticate-pam (Authentication)
- Purpose: PAM (Pluggable Authentication Modules) integration for system authentication
- Components:
authenticate_pam.node
: Node.js addon for system authenticationnode_modules/authenticate-pam/
: Full module with package.json, binding.gyp, and source files
- Platforms: Both macOS and Linux
- Dependencies: System PAM libraries
- Note: While macOS uses different authentication mechanisms internally (OpenDirectory), VibeTunnel attempts PAM authentication on both platforms as a fallback after SSH key authentication
- Critical: The entire authenticate-pam module directory must be included in the npm package, not just the prebuilds
Prebuild System
Overview
We useprebuild
and prebuild-install
to provide precompiled native modules, eliminating the need for users to have build tools installed.
Coverage
- Node.js versions: 20, 22, 23, 24
- Platforms: macOS (x64, arm64), Linux (x64, arm64)
- Total prebuilds: 24 binaries
- node-pty: 16 binaries (macOS and Linux, all architectures)
- authenticate-pam: 8 binaries (Linux only - macOS builds may fail due to PAM differences)
Prebuild Files
Build Process
Clean Build Approach
The npm build process uses a clean distribution directory approach that follows npm best practices:- Creates dist-npm/ directory - Separate from source files
- Generates clean package.json - Only production fields, no dev dependencies
- Bundles dependencies - node-pty is bundled directly, no symlinks needed
- Preserves source integrity - Never modifies source package.json
Unified Build (Multi-Platform by Default)
- Compiles TypeScript and bundles client code
- Builds native modules for all supported platforms (macOS x64/arm64, Linux x64/arm64)
- Creates comprehensive prebuilds for zero-dependency installation
- Generates npm README optimized for package distribution
- Creates clean dist-npm/ directory for packaging
Build Options
The unified build script supports flexible targeting:Docker Requirements
For Linux builds, Docker is required:- Recommended: OrbStack
- Alternative: Docker Desktop
Installation Process
For End Users
- Install package:
npm install -g vibetunnel
- Postinstall script runs: Extracts appropriate prebuilt binaries
- No compilation needed: Prebuilds included for all supported platforms
- Result: Working VibeTunnel installation without build tools
Key Improvements
- No symlinks: node-pty is bundled directly, avoiding postinstall symlink issues
- Clean package structure: Only production files in the npm package
- Reliable installation: Works in restricted environments (Docker, CI)
Installation Scripts
The package uses a simplified postinstall approach:Postinstall Process
- Prebuild extraction: Extracts the appropriate prebuild for the current platform
- No downloads: All prebuilds are included in the package
- No compilation: Everything is pre-built, no build tools required
- Platform detection: Automatically selects correct binary based on OS and architecture
Platform-Specific Details
macOS
- spawn-helper: Additional C binary needed for proper PTY operations (now prebuilt as universal binary)
- Authentication: Attempts PAM authentication but may fall back to environment variables or SSH keys
- Architecture: Supports both Intel (x64) and Apple Silicon (arm64)
- Build tools: Not required with prebuilds; Xcode Command Line Tools only needed for source compilation fallback
Linux
- PAM authentication: Full support via authenticate-pam module
- PAM libraries: Requires
libpam0g-dev
for authenticate-pam compilation from source - spawn-helper: Not used on Linux (macOS-only)
- Build tools: Not required with prebuilds;
build-essential
only needed for source compilation fallback
Docker Build Environment
Linux prebuilds are created using Docker with:- Base image:
node:22-bookworm
- Dependencies:
python3 make g++ git libpam0g-dev
- Package manager: pnpm (more reliable than npm in Docker)
- Environment:
CI=true
to avoid interactive prompts
spawn-helper Binary
What is spawn-helper?
spawn-helper
is a small C helper binary used by node-pty for proper terminal process spawning on macOS.
Key Facts
- Size: ~70KB pure C binary
- Platform: macOS only (Linux doesn’t use it)
- Purpose: Handles terminal device attachment for spawned processes
- Dependencies: None (pure C, no Node.js dependencies)
- Architecture: Platform-specific (x64 vs arm64)
Source Code
Installation Handling
- Current approach: Universal spawn-helper binary included in prebuilds (macOS only)
- Benefits: No compilation needed, faster installation, works without build tools
- Fallback path: If prebuild fails, compilation happens automatically via node-gyp
- Error handling: Non-fatal if missing (warns but continues)
Universal Binary Implementation
spawn-helper is now shipped as a prebuilt universal binary in all macOS prebuilds: Implementation:- Built for both x64 and arm64 architectures using clang++
- Combined into universal binary with
lipo
- Included in every macOS node-pty prebuild automatically
- ✅ Faster installation (no compilation needed)
- ✅ Works without build tools (Xcode Command Line Tools)
- ✅ Universal compatibility across Intel and Apple Silicon Macs
- ✅ Smaller download than compiling during install
Package Optimization
File Exclusions
Development artifacts are excluded from the final package:- Test files (
public/bundle/test.js
,public/test/
directory) - Recording files (
*.cast
prevented by .gitignore) - Build artifacts (
dist/
selectively included via package.jsonfiles
field)
Size Optimization
- Final size: ~8.5 MB
- File count: ~275 files
- Prebuilds: Included for zero-build installation experience
- Source code: Minimal, compiled assets only
Development Commands
Local Development
Quality Checks
Always run before publishing:Publishing
Prerequisites
- Update version in
package.json
- Run multi-platform build
- Test package locally
- Verify all prebuilds are included
Publish Command
Usage After Installation
Installation
Starting the Server
Using the vt Command
Command Forwarding
Coexistence with Mac App
The npm package works seamlessly alongside the Mac app:Command Routing
- The
vt
command from npm automatically detects if the Mac app is installed - If Mac app found at
/Applications/VibeTunnel.app
, npmvt
defers to it - Ensures you always get the best available implementation
Installation Behavior
- Won’t overwrite existing
/usr/local/bin/vt
from other tools - Provides helpful warnings if conflicts exist
- Installation always succeeds, even if
vt
symlink can’t be created - Use
vibetunnel
ornpx vt
as alternatives
Build Process Validation
Ensuring authenticate-pam Module is Included
Critical: The authenticate-pam module must be copied to the npm package during build. This was missing in beta 14 due to a hardcoded pnpm path issue.What to Check Before Publishing
-
Verify authenticate-pam is installed:
-
Run the build and check output:
-
Verify in the built package:
-
Test the package contents:
How the Build Script Works
ThecopyAuthenticatePam()
function in scripts/build-npm.js
:
- Searches multiple possible locations for the module (direct node_modules, pnpm structures)
- Uses
fs.statSync()
to properly follow symlinks - Logs which path was found or lists all searched paths if not found
- Copies the entire module directory to
dist-npm/node_modules/authenticate-pam/
If authenticate-pam is Missing
- Ensure it’s installed: Run
pnpm install
to install all dependencies - Check for optional dependency issues: authenticate-pam is listed as a regular dependency, not optional
- Verify pnpm didn’t clean it: Sometimes pnpm removes unused modules during cleanup
- Force reinstall if needed:
pnpm install authenticate-pam
Troubleshooting
Common Issues
Missing Build Tools
Error:gyp ERR! stack Error: not found: make
Solution: Install build tools:
- macOS:
xcode-select --install
- Linux:
apt-get install build-essential
Missing PAM Development Libraries
Error:fatal error: security/pam_appl.h: No such file or directory
Solution: Install PAM development libraries:
- Linux:
apt-get install libpam0g-dev
- macOS: Usually available by default
Docker Not Available
Error:Docker is required for multi-platform builds
Solution: Install Docker using OrbStack or Docker Desktop
Prebuild Download Failures
Error:prebuild-install warn install No prebuilt binaries found
Cause: Network issues or unsupported platform/Node version
Result: Automatic fallback to source compilation
npm_config_prefix Conflict with NVM
Error: Global npm installs fail or install to wrong location when using NVM Symptoms:npm install -g
installs packages to system location instead of NVM directory- Command not found errors after global install
- Permission errors during global installation
npm_config_prefix
environment variable overrides NVM’s per-version npm configuration
Detection: VibeTunnel’s postinstall script will warn if this conflict is detected:
npm_config_prefix
settings in:
~/.bashrc
~/.bash_profile
~/.profile
/etc/profile
- CI/CD environment configurations
- Previous system-wide npm installations
- Docker containers with npm pre-installed
- CI/CD environments with global npm configuration
- Package managers that set global npm prefix
Debugging Installation
Architecture Decisions
Why Prebuilds?
- User experience: No build tools required for most users
- Installation speed: Pre-compiled binaries install much faster
- Reliability: Eliminates compilation errors in user environments
- Cross-platform: Supports all target platforms without user setup
Why Docker for Linux Builds?
- Cross-compilation: Build Linux binaries from macOS development machine
- Consistency: Reproducible build environment
- Dependencies: Proper PAM library versions for Linux
Why Vendored node-pty?
- Control: Custom modifications for VibeTunnel’s needs
- Reliability: Avoid external dependency issues
- Optimization: Minimal implementation without unnecessary features
Related Files
scripts/build-npm.js
- Unified npm build process with multi-platform supportscripts/postinstall-npm.js
- Fallback compilation logic.prebuildrc
- Prebuild configuration for target platformspackage.json
- Package configuration and file inclusions
Release Notes
Version 1.0.0-beta.14.1 (2025-07-21)
Published to npm: Successfully published as bothvibetunnel@beta
and vibetunnel@latest
Critical Fix:
- Fixed missing authenticate-pam module that was excluded from the npm package in beta.14
- The build script now properly detects authenticate-pam in various pnpm directory structures
- Package size: 14.8 MB (34.4 MB unpacked)
- Contains 234 files including all prebuilds and web assets
- Includes all 24 prebuilds (16 node-pty + 8 authenticate-pam)
- authenticate-pam module is now properly bundled in
node_modules/authenticate-pam/
- Enhanced
copyAuthenticatePam()
function to search multiple pnpm locations - Added comprehensive logging to track which paths are searched
- Properly follows symlinks with
fs.statSync()
for accurate module detection
Version 1.0.0-beta.13 (2025-07-19)
Published to npm: Successfully published as bothvibetunnel@beta
and vibetunnel@latest
Key Features:
- All features from previous releases maintained
- Updated to match macOS app version 1.0.0-beta.13
- Full cross-platform support with prebuilt binaries
- Zero-dependency installation experience
- Package size: 15.5 MB (37.1 MB unpacked)
- Contains 235 files including all prebuilds and web assets
- Includes prebuilds for Node.js 20, 22, 23, and 24
Version 1.0.0-beta.11 (2025-07-16)
Published to npm: Successfully published asvibetunnel@beta
Key Features:
- Cross-platform support for macOS (x64, arm64) and Linux (x64, arm64)
- Pre-built native binaries for Node.js versions 20, 22, 23, and 24
- Zero-dependency installation experience (no build tools required)
- Comprehensive prebuild system with 24 total binaries included
-
Version Synchronization:
- Must update version in both
web/package.json
andmac/VibeTunnel/version.xcconfig
- Build process validates version sync to prevent mismatches
- Version mismatch will cause build failure with clear error message
- Must update version in both
-
NPM Publishing Requirements:
- Beta versions require
--tag beta
flag when publishing - Previously published versions cannot be overwritten (must increment version)
- Use
--access public
flag for public package publishing
- Beta versions require
-
Package Build Process:
pnpm run build:npm
creates the complete package with all prebuilds- Build output filename may show older version in logs but creates correct package
- Always verify package version in
dist-npm/package.json
before publishing
-
Docker Testing Verification:
- Successfully tested on Ubuntu 22.04 (both ARM64 and x64 architectures)
- Installation works without any build tools installed
- Server starts correctly with all expected functionality
- HTTP endpoints respond properly
-
Package Structure:
- Final package size: 8.3 MB (24.9 MB unpacked)
- Contains 198 files including all prebuilds and web assets
- Proper postinstall script ensures seamless installation
Version History
- 1.0.0-beta.14.1 (2025-07-21): Fixed authenticate-pam module missing from npm package (patch release)
- 1.0.0-beta.14 (2025-07-21): macOS app release (npm package had missing authenticate-pam module)
- 1.0.0-beta.13 (2025-07-19): Synchronized with macOS app version
- 1.0.0-beta.12.1 (2025-07-17): Minor updates and fixes
- 1.0.0-beta.12 (2025-07-17): Package structure improvements
- 1.0.0-beta.11.1 (2025-07-16): Fixed npm installation issues
- 1.0.0-beta.11 (2025-07-16): Initial release with full prebuild system
- 1.0.0-beta.10 (2025-07-14): Previous version (unpublished)
NPM Distribution Tags
VibeTunnel uses npm dist-tags to manage different release channels:Current Tags
- latest: Points to the most stable release (currently 1.0.0-beta.14.1)
- beta: Points to the latest beta release (currently 1.0.0-beta.14.1)
Managing Tags
Installation by Tag
Best Practices
- Always tag beta releases with
beta
tag - Only promote to
latest
after testing confirms stability - Use semantic versioning for beta iterations (e.g., 1.0.0-beta.11.1, 1.0.0-beta.11.2)