CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-prebuild

A command line tool for easily making prebuilt binaries for multiple versions of Node.js, Electron or node-webkit on a specific platform

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

utilities.mddocs/

Utilities

Common utility functions for file operations, process spawning, path generation, packaging, and debug symbol stripping used throughout the prebuild system.

Capabilities

Path Generation

Generate standardized paths for prebuilt binary archives.

/**
 * Generate tar file path for prebuilt binary
 * @param opts - Options containing package info, platform, arch, runtime settings
 * @param abi - ABI version string (e.g., '93' for Node.js or '3' for Node-API)
 * @returns Generated tar file path in prebuilds directory
 */
function getTarPath(opts, abi): string;

interface TarPathOptions {
  pkg: PackageJson;
  runtime: Runtime;
  platform: string;
  arch: string;
  libc?: string;
}

interface PackageJson {
  name: string;
  version: string;
}

type Runtime = 'node' | 'napi' | 'electron' | 'node-webkit';

Usage Examples:

const { getTarPath } = require('prebuild/util');

// Generate path for Node.js binary
const nodePath = getTarPath({
  pkg: { name: 'mymodule', version: '1.0.0' },
  runtime: 'node',
  platform: 'linux', 
  arch: 'x64',
  libc: ''
}, '93');
// Returns: 'prebuilds/mymodule-v1.0.0-node-v93-linux-x64.tar.gz'

// Generate path for Electron binary
const electronPath = getTarPath({
  pkg: { name: 'mymodule', version: '1.0.0' },
  runtime: 'electron',
  platform: 'darwin',
  arch: 'x64'
}, '109');
// Returns: 'prebuilds/mymodule-v1.0.0-electron-v109-darwin-x64.tar.gz'

// Generate path with LIBC variant
const muslPath = getTarPath({
  pkg: { name: 'mymodule', version: '1.0.0' },
  runtime: 'node',
  platform: 'linux',
  arch: 'x64', 
  libc: 'musl'
}, '93');
// Returns: 'prebuilds/mymodule-v1.0.0-node-v93-linux-musl-x64.tar.gz'

Process Spawning

Utilities for spawning child processes with proper error handling.

/**
 * Spawn child process with error handling
 * @param cmd - Command to execute
 * @param args - Array of command arguments
 * @param cb - Callback function (err) => void
 * @returns ChildProcess instance
 */
function spawn(cmd, args, cb): ChildProcess;

/**
 * Fork Node.js process with error handling
 * @param file - JavaScript file to fork
 * @param cb - Callback function (err) => void
 * @returns ChildProcess instance
 */
function fork(file, cb): ChildProcess;

/**
 * Execute shell command with inherit stdio
 * @param cmd - Shell command to execute
 * @param cb - Callback function (err) => void
 * @returns ChildProcess instance
 */
function exec(cmd, cb): ChildProcess;

Usage Examples:

const { spawn, fork, exec } = require('prebuild/util');

// Spawn a process
spawn('node-gyp', ['rebuild'], (err) => {
  if (err) {
    console.error('node-gyp failed:', err.message);
  } else {
    console.log('Build completed');
  }
});

// Fork a JavaScript file
fork('./build-script.js', (err) => {
  if (err) {
    console.error('Script failed:', err.message);
  } else {
    console.log('Script completed');
  }
});

// Execute shell command
exec('npm install', (err) => {
  if (err) {
    console.error('Install failed:', err.message);
  } else {
    console.log('Dependencies installed');
  }
});

Smart Process Execution

Execute either shell commands or JavaScript files based on file extension.

/**
 * Execute shell command or JavaScript file based on extension
 * @param item - Shell command string or path to .js file
 * @param cb - Callback function (err) => void
 * @returns ChildProcess instance
 */
function run(item, cb): ChildProcess;

Usage Examples:

const { run } = require('prebuild/util');

// Execute JavaScript file (detected by .js extension)
run('./setup.js', (err) => {
  if (err) throw err;
  console.log('Setup script completed');
});

// Execute shell command
run('chmod +x ./binary', (err) => {
  if (err) throw err;
  console.log('Permissions updated');
});

// Cross-platform script execution
run(process.platform === 'win32' ? 'setup.bat' : './setup.sh', (err) => {
  if (err) throw err;
  console.log('Platform-specific setup completed');
});

Platform Detection

Get current platform information.

/**
 * Get current platform
 * @returns Platform string (e.g., 'linux', 'darwin', 'win32')
 */
function platform(): string;

Usage Examples:

const { platform } = require('prebuild/util');

const currentPlatform = platform();
console.log('Building on:', currentPlatform);

// Platform-specific logic
if (platform() === 'win32') {
  console.log('Windows-specific build steps');
} else {
  console.log('Unix-like build steps');
}

Release Folder Detection

Determine the correct build output folder based on backend and configuration.

/**
 * Get build output folder path
 * @param opts - Build options including debug flag, backend, and package config
 * @param version - Target version being built
 * @returns Path to build output directory
 */
function releaseFolder(opts, version): string;

interface ReleaseFolderOptions {
  debug?: boolean;
  backend?: Backend;
  pkg?: {
    binary?: {
      module_path?: string;
    };
  };
}

type Backend = 'node-gyp' | 'node-ninja' | 'nw-gyp' | 'cmake-js';

Usage Examples:

const { releaseFolder } = require('prebuild/util');

// Standard Release build
const releaseDir = releaseFolder({
  debug: false,
  backend: 'node-gyp'
}, '16.14.0');
// Returns: 'build/Release'

// Debug build
const debugDir = releaseFolder({
  debug: true,
  backend: 'node-gyp'
}, '16.14.0');
// Returns: 'build/Debug'

// node-ninja backend with version-specific folder
const ninjaDir = releaseFolder({
  debug: false,
  backend: 'node-ninja'
}, '16.14.0');
// Returns: 'build/16.14.0/Release'

// Custom module path from package.json
const customDir = releaseFolder({
  debug: false,
  pkg: {
    binary: {
      module_path: './lib/binding'
    }
  }
}, '16.14.0');
// Returns: './lib/binding'

Binary Packaging

Package build artifacts into compressed tar.gz archives.

/**
 * Package files into compressed tar.gz archive
 * @param filenames - File or array of files to package
 * @param tarPath - Output tar.gz file path
 * @param cb - Callback function (err) => void
 */
function pack(filenames, tarPath, cb): void;

Usage Examples:

const pack = require('prebuild/pack');

// Package single file
pack('build/Release/module.node', 'prebuilds/module-v1.0.0-node-v93-linux-x64.tar.gz', (err) => {
  if (err) throw err;
  console.log('Binary packaged successfully');
});

// Package multiple files
pack([
  'build/Release/module.node',
  'build/Release/helper.node'
], 'prebuilds/module-v1.0.0-node-v93-linux-x64.tar.gz', (err) => {
  if (err) throw err;
  console.log('All binaries packaged');
});

Debug Symbol Stripping

Remove debug symbols from native binaries to reduce file size.

/**
 * Strip debug symbols from binary files (platform-specific)
 * @param files - Array of file paths to strip
 * @param cb - Callback function (err) => void
 */
function strip(files, cb): void;

Usage Examples:

const strip = require('prebuild/strip');

// Strip debug symbols from binaries
strip(['build/Release/module.node'], (err) => {
  if (err) throw err;
  console.log('Debug symbols stripped');
});

// Strip multiple files
strip([
  'build/Release/module.node',
  'build/Release/helper.so'
], (err) => {
  if (err) throw err;
  console.log('All files stripped');
});

Platform-specific strip behavior:

  • macOS: Uses strip -Sx to strip debug symbols while preserving dynamic symbol table
  • Linux/FreeBSD: Uses strip --strip-all to remove all symbols
  • Windows: No-op (debug symbols stripped during build)
  • Other platforms: No arguments passed to strip command

Error Handling

Standard error creation utilities.

/**
 * Create error for missing build artifacts
 * @param folder - Build folder that was searched
 * @returns Error instance
 */
function noBuild(folder): Error;

/**
 * Create error for missing repository configuration
 * @returns Error instance
 */
function noRepository(): Error;

/**
 * Create error for failed subprocess execution
 * @param cmd - Command that failed
 * @param args - Command arguments
 * @param code - Exit code
 * @returns Error instance
 */
function spawnFailed(cmd, args, code): Error;

Usage Examples:

const { noBuild, noRepository, spawnFailed } = require('prebuild/error');

// Build artifact missing
throw noBuild('build/Release');
// Error: Could not find build in build/Release

// Repository configuration missing
throw noRepository();
// Error: package.json is missing a repository field

// Process execution failed
throw spawnFailed('node-gyp', ['rebuild'], 1);
// Error: node-gyp rebuild failed with exit code 1

Types

interface PackageJson {
  name: string;
  version: string;
  binary?: {
    module_name?: string;
    module_path?: string;
  };
}

type Runtime = 'node' | 'napi' | 'electron' | 'node-webkit';
type Backend = 'node-gyp' | 'node-ninja' | 'nw-gyp' | 'cmake-js';

interface ChildProcess {
  pid: number;
  stdout: Readable;
  stderr: Readable;
  stdin: Writable;
}

Install with Tessl CLI

npx tessl i tessl/npm-prebuild

docs

build-system.md

configuration.md

index.md

upload-system.md

utilities.md

tile.json