Skip to content

Download Tarball Examples ​

This page demonstrates how to use the DownloadTarball method to download NPM package tarballs to local files.

Download Flow ​

DownloadTarball first resolves the version (querying dist-tags when you pass latest), then streams dist.tarball into the target file — avoiding loading the whole package into memory:

Example 1: Download Specific Version ​

go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/scagogogo/npm-skills/pkg/registry"
)

func main() {
    client := registry.NewRegistry()
    ctx := context.Background()

    packageName := "axios"
    version := "1.0.0"
    destPath := "./axios-1.0.0.tgz"

    // Remove existing file if present
    os.Remove(destPath)

    fmt.Printf("Downloading %s@%s...\n", packageName, version)

    err := client.DownloadTarball(ctx, packageName, version, destPath)
    if err != nil {
        log.Fatalf("Download failed: %v", err)
    }

    // Verify the file
    info, err := os.Stat(destPath)
    if err != nil {
        log.Fatalf("File stat failed: %v", err)
    }

    fmt.Printf("Download successful!\n")
    fmt.Printf("File size: %d bytes\n", info.Size())
}
go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/scagogogo/npm-skills/pkg/registry"
)

func main() {
    // Use CNPM mirror for faster downloads
    options := registry.NewOptions().SetRegistryURL(registry.RegistryUrlCnpm)
    client := registry.NewRegistry(options)

    ctx := context.Background()
    packageName := "react"
    version := "18.2.0"
    destDir := "/tmp/npm-tarballs"

    // Ensure destination directory exists
    if err := os.MkdirAll(destDir, 0755); err != nil {
        log.Fatalf("Failed to create directory: %v", err)
    }

    destPath := fmt.Sprintf("%s/%s-%s.tgz", destDir, packageName, version)
    os.Remove(destPath)

    fmt.Printf("Downloading %s@%s using CNPM mirror...\n", packageName, version)

    err := client.DownloadTarball(ctx, packageName, version, destPath)
    if err != nil {
        log.Fatalf("Download failed: %v", err)
    }

    info, _ := os.Stat(destPath)
    fmt.Printf("Download successful! File size: %d bytes\n", info.Size())
}

Example 3: Download Latest Version ​

go
package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "github.com/scagogogo/npm-skills/pkg/registry"
)

func main() {
    client := registry.NewRegistry()
    ctx := context.Background()

    packageName := "vue"
    version := "latest"
    destPath := "./vue-latest.tgz"

    // Get version info first
    versionInfo, err := client.GetPackageVersion(ctx, packageName, version)
    if err != nil {
        log.Fatalf("Failed to get version info: %v", err)
    }

    fmt.Printf("Latest version: %s\n", versionInfo.Version)

    os.Remove(destPath)
    err = client.DownloadTarball(ctx, packageName, version, destPath)
    if err != nil {
        log.Fatalf("Download failed: %v", err)
    }

    info, _ := os.Stat(destPath)
    fmt.Printf("Download successful! File size: %d bytes\n", info.Size())
}

Example 4: Batch Download Multiple Packages ​

When downloading in bulk, multiple goroutines share a single Registry instance (its internal *http.Client and connection pool are concurrency-safe), each writing to disk independently without blocking each other:

go
package main

import (
    "context"
    "fmt"
    "log"
    "os"
    "path/filepath"
    "sync"

    "github.com/scagogogo/npm-skills/pkg/registry"
)

func main() {
    client := registry.NewRegistry()
    ctx := context.Background()

    packages := []struct {
        name    string
        version string
    }{
        {"react", "18.2.0"},
        {"vue", "3.4.0"},
        {"angular", "17.3.0"},
    }

    destDir := "/tmp/npm-packages"
    os.MkdirAll(destDir, 0755)

    var wg sync.WaitGroup

    for _, pkg := range packages {
        wg.Add(1)
        go func(name, version string) {
            defer wg.Done()

            destPath := filepath.Join(destDir, fmt.Sprintf("%s-%s.tgz", name, version))
            os.Remove(destPath)

            err := client.DownloadTarball(ctx, name, version, destPath)
            if err != nil {
                log.Printf("Failed to download %s@%s: %v\n", name, version, err)
                return
            }

            info, _ := os.Stat(destPath)
            fmt.Printf("✅ %s@%s: %d bytes\n", name, version, info.Size())
        }(pkg.name, pkg.version)
    }

    wg.Wait()
    fmt.Println("All downloads complete!")
}

Run the Examples ​

bash
go mod init tarball-example
go get github.com/scagogogo/npm-skills
go run main.go

Next Steps ​

Released under the MIT License.