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

@infrasamurai/hetzner

v0.0.1

Published

Hetzner Cloud provider for InfraSamurai hosting

Readme

@infrasamurai/hetzner

Hetzner Cloud provider implementation for InfraSamurai hosting.

Installation

npm install @infrasamurai/hetzner
# or
yarn add @infrasamurai/hetzner

Quick Start

import { HetznerProvider } from '@infrasamurai/hetzner';

const hetzner = new HetznerProvider('your-hetzner-api-token');

// Validate credentials
const { valid, error } = await hetzner.validateCredentials();

// Get available resources
const locations = await hetzner.getLocations();
const serverTypes = await hetzner.getServerTypes('fsn1');
const images = await hetzner.getImages();
const networks = await hetzner.getNetworks();

// Create a server
const server = await hetzner.createServer({
  name: 'my-server',
  serverType: 'cx21',
  image: 'ubuntu-22.04',
  location: 'fsn1',
  sshKeyIds: ['12345'],
  providerOptions: {
    networks: ['67890'],
    enablePublicIpv4: true,
    enablePublicIpv6: true,
  },
});

// Wait for server to be ready
const details = await hetzner.waitForServerReady(server.serverId);
console.log(`Server running at ${details.publicIpv4}`);

// Delete server
await hetzner.deleteServer(server.serverId);

API

Constructor

const hetzner = new HetznerProvider(apiToken: string, options?: BaseProviderOptions);

Options:

  • logger - Custom logger implementing ProviderLogger
  • httpTimeout - Request timeout in ms (default: 30000)
  • maxRetries - Max retry attempts (default: 3)
  • retryDelayMs - Initial retry delay in ms (default: 1000)
  • pollInterval - Polling interval for waitForServerReady (default: 5000)
  • maxWaitTime - Max wait time for waitForServerReady (default: 300000)

Methods

Credentials

validateCredentials(): Promise<{ valid: boolean; error?: string }>

Locations

getLocations(): Promise<ServerLocation[]>

Returns Hetzner datacenters: fsn1, nbg1, hel1, ash, hil.

Server Types

getServerTypes(location?: string): Promise<ServerType[]>

Returns available server sizes. Filter by location to get accurate pricing.

Images

getImages(): Promise<ServerImage[]>

Returns available OS images (Ubuntu, Debian, CentOS, etc.).

SSH Keys

getSshKeys(): Promise<ProviderSshKey[]>
createSshKey(name: string, publicKey: string): Promise<ProviderSshKey>
deleteSshKey(keyId: string): Promise<void>

Networks

getNetworks(): Promise<ProviderNetwork[]>

Returns private networks for internal server communication.

Servers

createServer(request: CreateServerRequest): Promise<CreateServerResponse>
getServer(serverId: string): Promise<ServerDetails>
waitForServerReady(serverId: string, timeoutMs?: number): Promise<ServerDetails>
deleteServer(serverId: string): Promise<void>

CreateServerRequest

interface CreateServerRequest {
  name: string;
  serverType: string;           // e.g., 'cx21', 'cpx11'
  image: string;                // e.g., 'ubuntu-22.04'
  location: string;             // e.g., 'fsn1'
  sshKeyIds?: string[];         // Hetzner SSH key IDs
  userData?: string;            // Cloud-init script
  labels?: Record<string, string>;
  providerOptions?: {
    networks?: string[];        // Network IDs to attach
    firewalls?: string[];       // Firewall IDs to apply
    enablePublicIpv4?: boolean; // Default: true
    enablePublicIpv6?: boolean; // Default: true
    placementGroup?: string;    // Placement group ID
    volumes?: string[];         // Volume IDs to attach
  };
}

UI Schema

The package exports a UI schema for building dynamic forms:

import { hetznerUISchema } from '@infrasamurai/hetzner';

console.log(hetznerUISchema.displayName);  // "Hetzner Cloud"
console.log(hetznerUISchema.capabilities); // Available features

Capabilities

  • Private Networks
  • Cloud Firewalls
  • Load Balancers
  • Block Storage (Volumes)
  • Floating IPs
  • Snapshots
  • Automatic Backups
  • Placement Groups
  • Primary IPs

Hetzner Cloud API

This provider uses the Hetzner Cloud API v1.

Getting an API Token

  1. Log in to Hetzner Cloud Console
  2. Select your project
  3. Go to Security > API Tokens
  4. Click Generate API Token
  5. Give it a name and select Read & Write permissions

Error Handling

import { HostingError, HostingErrorType } from '@infrasamurai/hosting-core';

try {
  await hetzner.createServer({ ... });
} catch (error) {
  if (error instanceof HostingError) {
    switch (error.errorType) {
      case HostingErrorType.QUOTA_EXCEEDED:
        console.error('Server limit reached');
        break;
      case HostingErrorType.API_RATE_LIMITED:
        console.error('Rate limited, retry later');
        break;
      case HostingErrorType.API_AUTH_FAILED:
        console.error('Invalid API token');
        break;
    }
  }
}

License

MIT