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

@crumblecracker/cc

v0.1.1

Published

TypeScript bindings for the cc virtualization library

Readme

@crumblecracker/cc

TypeScript bindings for the cc virtualization library. Works on Node.js 18+ and Bun.

Installation

npm install @crumblecracker/cc

Requirements

  • Node.js 18+ or Bun
  • cc-helper binary (for VM operations)
  • Hypervisor support (macOS with Apple Silicon, or Linux with KVM)

Quick Start

import {
  init,
  shutdown,
  apiVersion,
  supportsHypervisor,
  OCIClient,
} from '@crumblecracker/cc';

// Initialize library
init();

// Check version
console.log(apiVersion()); // "0.1.0"

// Check hypervisor
const available = supportsHypervisor();
console.log(`Hypervisor available: ${available}`);

// OCI Client usage
const client = new OCIClient();
const source = await client.pull('alpine:latest');

// Create instance with "await using" for automatic cleanup
await using inst = await source.createInstance({
  memoryMb: 256,
  cpus: 1,
});

console.log(`Instance ID: ${await inst.id()}`);
console.log(`Running: ${await inst.isRunning()}`);

// Run command
const cmd = await inst.command('echo', 'Hello from Node.js!');
const output = await cmd.output();
console.log(output.toString());

// File operations
await inst.writeFile('/tmp/test.txt', Buffer.from('Hello'));
const data = await inst.readFile('/tmp/test.txt');
console.log(data.toString());

// Cleanup
await source.helper.close();
client.close();
shutdown();

API Reference

Library Functions

// Version info
apiVersion(): string
apiVersionCompatible(major: number, minor: number): boolean
guestProtocolVersion(): number

// Lifecycle
init(): void
shutdown(): void

// Capabilities
supportsHypervisor(): boolean
queryCapabilities(): Promise<Capabilities>

OCIClient

const client = new OCIClient(cacheDir?: string);

// Pull from registry
const source = await client.pull('alpine:latest', options?: PullOptions);

// Load from local files
const source = await client.loadTar('/path/to/image.tar');
const source = await client.loadDir('/path/to/rootfs');

// Cleanup
client.close();

Instance

// Create instance
await using inst = await source.createInstance(options?: InstanceOptions);

// Properties
await inst.id(): Promise<string>
await inst.isRunning(): Promise<boolean>

// Filesystem operations
await inst.readFile(path: string): Promise<Buffer>
await inst.writeFile(path: string, data: Buffer, mode?: number): Promise<void>
await inst.stat(path: string): Promise<FileInfo>
await inst.mkdir(path: string, mode?: number): Promise<void>
await inst.remove(path: string): Promise<void>
await inst.removeAll(path: string): Promise<void>
await inst.readDir(path: string): Promise<DirEntry[]>

// File handles
await using file = await inst.open(path: string): Promise<File>
await using file = await inst.create(path: string): Promise<File>

// Commands
const cmd = await inst.command('echo', 'hello');
const output = await cmd.output();
const exitCode = await cmd.run();

// Networking
const listener = await inst.listen('tcp', ':8080');
const conn = await listener.accept();

// Cleanup
await inst.close();

File

await using file = await inst.open('/path/to/file');

await file.read(size?: number): Promise<Buffer>
await file.write(data: Buffer): Promise<number>
await file.seek(offset: number, whence?: SeekWhence): Promise<number>
await file.stat(): Promise<FileInfo>
await file.sync(): Promise<void>
await file.truncate(size: number): Promise<void>
await file.close(): Promise<void>

Command

const cmd = await inst.command('sh', '-c', 'echo hello');

// Configure
await cmd.setDir('/tmp');
await cmd.setEnv('KEY', 'value');

// Execute
const output = await cmd.output();           // stdout
const combined = await cmd.combinedOutput(); // stdout + stderr
const exitCode = await cmd.run();            // just run

// Async execution
await cmd.start();
const exitCode = await cmd.wait();

Types

InstanceOptions

interface InstanceOptions {
  memoryMb?: number;      // Default: 256
  cpus?: number;          // Default: 1
  timeoutSeconds?: number;
  user?: string;
  enableDmesg?: boolean;
  mounts?: MountConfig[];
}

FileInfo

interface FileInfo {
  name: string;
  size: number;
  mode: number;
  modTimeUnix: number;
  isDir: boolean;
  isSymlink: boolean;
}

DirEntry

interface DirEntry {
  name: string;
  isDir: boolean;
  mode: number;
}

Error Handling

All errors inherit from CCError:

import {
  CCError,
  InvalidHandleError,
  InvalidArgumentError,
  NotRunningError,
  AlreadyClosedError,
  TimeoutError,
  HypervisorUnavailableError,
  IOError,
  NetworkError,
  CancelledError,
} from '@crumblecracker/cc';

try {
  await inst.readFile('/nonexistent');
} catch (err) {
  if (err instanceof IOError) {
    console.error('File not found:', err.message);
  }
}

Resource Management

Use await using (ES2022 Explicit Resource Management) for automatic cleanup:

// Automatic cleanup when scope exits
await using inst = await source.createInstance();
await using file = await inst.create('/tmp/test.txt');

// Or manual cleanup
const inst = await source.createInstance();
try {
  // ... use instance
} finally {
  await inst.close();
}

Environment Variables

  • CC_HELPER_PATH - Path to cc-helper binary
  • CC_RUN_VM_TESTS - Set to 1 to run VM integration tests

Development

# Install dependencies
npm install

# Build
npm run build

# Run tests
npm test

# Run VM tests (requires hypervisor)
CC_RUN_VM_TESTS=1 npm test

License

MIT