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

@zenyr/bun-pty

v0.4.4

Published

Cross-platform pseudoterminal (PTY) implementation for Bun with native performance (fork of bun-pty)

Readme

@zenyr/bun-pty

NPM Version License: MIT Bun Compatible

A cross-platform pseudo-terminal (PTY) implementation for Bun runtime, powered by Rust's portable-pty library and Bun's FFI capabilities.

⚠️ Bun Runtime Required: This package uses bun:ffi and Bun-specific APIs. For Node.js, please use node-pty instead.

Note: This is a fork of bun-pty (v0.3.2) with significant improvements and architectural changes.

🔀 Fork Improvements (v0.3.3+)

This fork adds the following improvements over the original bun-pty:

Performance & Distribution

  • Platform-specific packages: Split native libraries into optional dependencies (~600KB vs ~3-4MB)
  • ARM64 support: Added native support for ARM64 on both Linux and macOS

Bug Fixes

  • Exit code handling: Fixed issue where child process exit codes were not properly captured
  • FFI bindings: Corrected bun_pty_write FFI bindings and removed unnecessary null terminators
  • Argument quoting: Fixed bash argument handling for commands with spaces and special characters

Developer Experience

  • Enhanced error messages: Better library resolution errors with platform detection
  • Custom library path: Support for BUN_PTY_LIB environment variable
  • Comprehensive tests: Added exit code verification and vi integration tests
  • Security: Pinned GitHub Actions versions and fixed workflow vulnerabilities

CI/CD & Publishing

  • Cross-platform builds: Automated builds for all platforms (Linux/macOS/Windows, x64/ARM64)
  • Multi-package publishing: Automated publishing of platform-specific packages to npm

🔄 Upstream Contributions

The following improvements have been submitted as pull requests to the upstream repository:

These fixes are already included in this fork (v0.3.3+) and are pending review in the upstream repository.

🚀 Features

  • Cross-platform - Works on macOS, Linux, and Windows
  • Simple API - Clean Promise-based API similar to node-pty
  • Type-safe - Complete TypeScript definitions included
  • Efficient - Rust backend with proper error handling and multithreading
  • Zero dependencies - No external JavaScript dependencies required
  • Modern - Built specifically for Bun using its FFI capabilities

📦 Installation

From npm (recommended)

bun add @zenyr/bun-pty

The package automatically installs the correct native library for your platform. Platform-specific packages are installed as optional dependencies:

  • @zenyr/bun-pty-linux-x64 - Linux x86_64
  • @zenyr/bun-pty-linux-arm64 - Linux ARM64
  • @zenyr/bun-pty-darwin-x64 - macOS x86_64 (Intel)
  • @zenyr/bun-pty-darwin-arm64 - macOS ARM64 (Apple Silicon)
  • @zenyr/bun-pty-win32-x64 - Windows x86_64

Note: Only the platform-specific package matching your system will be downloaded, keeping installation size minimal (~600KB instead of ~3-4MB).

From GitHub (for development or specific branches)

Installing from GitHub requires building from source (Rust toolchain needed):

bun add github:zenyr/bun-pty --trust

Important: GitHub installations include source code and require the Rust toolchain (cargo) to build. Bun requires explicit permission to run build scripts. Use the --trust flag or add to trustedDependencies:

{
  "dependencies": {
    "@zenyr/bun-pty": "github:zenyr/bun-pty"
  },
  "trustedDependencies": [
    "@zenyr/bun-pty"
  ]
}

Tip: For production use, prefer the npm package which includes prebuilt binaries and doesn't require Rust.

⚙️ Requirements

  • Bun 1.0.0 or higher
  • Rust toolchain (cargo) is required only when installing from GitHub or building from source
  • TypeScript (included as devDependency)

📋 Platform Support

| Platform | Status | Notes | |----------|--------|-------| | macOS | ✅ | Fully supported | | Linux | ✅ | Fully supported | | Windows | ✅ | Fully supported |

🚦 Usage

Basic Example

import { spawn } from "@zenyr/bun-pty";

// Create a new terminal
const terminal = spawn("bash", [], {
  name: "xterm-256color",
  cols: 80,
  rows: 24
});

// Handle data from the terminal
terminal.onData((data) => {
  console.log("Received:", data);
});

// Handle terminal exit
terminal.onExit(({ exitCode, signal }) => {
  console.log(`Process exited with code ${exitCode} and signal ${signal}`);
});

// Write to the terminal
terminal.write("echo Hello from Bun PTY\n");

// Resize the terminal
terminal.resize(100, 40);

// Kill the process when done
setTimeout(() => {
  terminal.kill();
}, 5000);

TypeScript Usage

The library includes complete TypeScript definitions. Here's how to use it with full type safety:

import { spawn } from "@zenyr/bun-pty";
import type { IPty, IExitEvent, IPtyForkOptions } from "@zenyr/bun-pty";

// Create typed options
const options: IPtyForkOptions = {
  name: "xterm-256color",
  cols: 100,
  rows: 30,
  cwd: process.cwd()
};

// Create a terminal with proper typing
const terminal: IPty = spawn("bash", [], options);

// Typed event handlers
const dataHandler = terminal.onData((data: string) => {
  process.stdout.write(data);
});

const exitHandler = terminal.onExit((event: IExitEvent) => {
  console.log(`Process exited with code: ${event.exitCode}`);
});

// Clean up when done
dataHandler.dispose();
exitHandler.dispose();

Interactive Shell Example

import { spawn } from "@zenyr/bun-pty";
import { createInterface } from "node:readline";

// Create a PTY running bash
const pty = spawn("bash", [], {
  name: "xterm-256color",
  cwd: process.cwd()
});

// Forward PTY output to stdout
pty.onData((data) => {
  process.stdout.write(data);
});

// Send user input to the PTY
process.stdin.on("data", (data) => {
  pty.write(data.toString());
});

// Handle PTY exit
pty.onExit(() => {
  console.log("Terminal session ended");
  process.exit(0);
});

// Handle SIGINT (Ctrl+C)
process.on("SIGINT", () => {
  pty.kill();
});

📖 API Reference

spawn(file: string, args: string[], options: IPtyForkOptions): IPty

Creates and spawns a new pseudoterminal.

  • file: The executable to launch
  • args: Arguments to pass to the executable
  • options: Configuration options
    • name: Terminal name (e.g., "xterm-256color")
    • cols: Number of columns (default: 80)
    • rows: Number of rows (default: 24)
    • cwd: Working directory (default: process.cwd())
    • env: Environment variables

Returns an IPty instance.

IPty Interface

interface IPty {
  // Properties
  readonly pid: number;        // Process ID
  readonly cols: number;       // Current columns
  readonly rows: number;       // Current rows
  readonly process: string;    // Process name
  
  // Events
  onData: (listener: (data: string) => void) => IDisposable;
  onExit: (listener: (event: IExitEvent) => void) => IDisposable;
  
  // Methods
  write(data: string): void;   // Write data to terminal
  resize(cols: number, rows: number): void;  // Resize terminal
  kill(signal?: string): void;  // Kill the process
}

Event Types

interface IExitEvent {
  exitCode: number;
  signal?: number | string;
}

interface IDisposable {
  dispose(): void;
}

🔧 Building from Source

If you want to build the package from source:

# Clone the repository
git clone https://github.com/zenyr/bun-pty.git
cd bun-pty

# Install dependencies
bun install

# Build Rust library and TypeScript
bun run build

# Run tests
bun test

❓ Troubleshooting

Prebuilt Binaries

The npm package uses platform-specific optional dependencies to provide prebuilt binaries. Each platform package contains only the native library for that specific OS and architecture.

If you encounter issues with the prebuilt binaries:

  1. Check if the platform package was installed:

    ls node_modules/@zenyr/bun-pty-*/
  2. Force reinstall the platform package:

    bun add @zenyr/bun-pty --force
  3. Build from source (development only):

    cd node_modules/@zenyr/bun-pty
    bun run build

Custom Library Path

You can specify a custom path to the native library using the BUN_PTY_LIB environment variable:

export BUN_PTY_LIB=/path/to/librust_pty.dylib
bun run your-script.ts

Common Issues

  • Error: librust_pty shared library not found

    • Make sure the appropriate platform package is installed
    • Check that your OS and architecture match one of the supported platforms
    • Try reinstalling with bun add @zenyr/bun-pty --force
  • Error: Unable to load shared library

    • Ensure you have the necessary system libraries installed
    • On Linux, you may need libc6 and related dependencies
  • Process spawn fails

    • Check if you have the required permissions and paths
    • Verify the executable exists and is in your PATH

📄 License

This project is licensed under the MIT License.

🙏 Credits