CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-download

Download and extract files from URLs with support for archives and HTTP streaming

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

Download

Download is a Node.js library that provides file downloading and optional archive extraction from URLs. It offers both Promise-based and stream-based APIs with robust HTTP request handling, automatic filename detection, and comprehensive archive format support through the decompress library.

Package Information

  • Package Name: download
  • Package Type: npm
  • Language: JavaScript
  • Installation: npm install download

Core Imports

const download = require('download');

Basic Usage

const fs = require('fs');
const download = require('download');

(async () => {
  // Download and save to directory
  await download('https://example.com/file.jpg', 'dist');
  
  // Download and get buffer
  const buffer = await download('https://example.com/file.jpg');
  fs.writeFileSync('downloaded-file.jpg', buffer);
  
  // Use as stream
  download('https://example.com/file.jpg').pipe(fs.createWriteStream('file.jpg'));
  
  // Download and extract archive
  await download('https://example.com/archive.zip', 'dist', { extract: true });
})();

Architecture

The download package is built around a single function that returns both a Promise and a Stream:

  • Dual Interface: The returned object is both a readable stream and a thenable Promise
  • HTTP Client: Uses the got library for robust HTTP handling with proxy support
  • Archive Detection: Automatically detects archive formats using archive-type
  • Filename Resolution: Intelligently determines filenames from URLs, headers, and file content
  • Stream Processing: Leverages Node.js streams for memory-efficient handling of large files

Capabilities

File Downloading

Core functionality for downloading files from URLs with flexible output options.

/**
 * Download a file from a URL
 * @param uri - URL to download from
 * @param output - Optional destination directory path
 * @param opts - Optional configuration options
 * @returns Stream & Promise<Buffer> - Duplex stream that also acts as a Promise
 */
function download(uri, output?, opts?) : Stream & Promise<Buffer>;

Configuration Options

Options object that accepts all got HTTP client options plus download-specific settings.

interface DownloadOptions {
  /** Whether to extract archive files (default: false) */
  extract?: boolean;
  /** Custom filename for saved file */
  filename?: string;
  /** Character encoding for response (default: null for binary) */
  encoding?: string | null;
  /** Whether to reject unauthorized SSL certificates */
  rejectUnauthorized?: boolean;
  /** All got HTTP client options are also supported */
  [key: string]: any;
}

Return Value Interface

The function returns an object that acts as both a readable stream and a Promise.

interface DownloadReturn extends Stream {
  /** Promise interface - resolves to Buffer containing file data */
  then<T>(onFulfilled?: (value: Buffer) => T | Promise<T>): Promise<T>;
  /** Promise interface - handles promise rejections */
  catch<T>(onRejected?: (reason: any) => T | Promise<T>): Promise<T>;
}

Stream Events

Inherits all standard Node.js stream events plus additional events from the got HTTP client.

// Standard stream events
download(url).on('data', (chunk) => { /* handle data chunk */ });
download(url).on('end', () => { /* download complete */ });
download(url).on('error', (err) => { /* handle error */ });

// Got-specific events  
download(url).on('response', (response) => { /* HTTP response received */ });
download(url).on('request', (request) => { /* HTTP request sent */ });

Usage Patterns

Promise Usage

// Basic promise usage
const buffer = await download('https://example.com/file.pdf');

// With error handling
try {
  const data = await download('https://example.com/file.zip');
  console.log('Downloaded', data.length, 'bytes');
} catch (error) {
  console.error('Download failed:', error.message);
}

Stream Usage

const fs = require('fs');

// Pipe to file
download('https://example.com/large-file.zip')
  .pipe(fs.createWriteStream('output.zip'));

// Handle stream events
const stream = download('https://example.com/file.dat');
stream.on('data', chunk => console.log('Received', chunk.length, 'bytes'));
stream.on('end', () => console.log('Download complete'));

File Saving

// Save to directory with original filename
await download('https://example.com/photo.jpg', 'downloads');

// Save with custom filename
await download('https://example.com/file.dat', 'downloads', { 
  filename: 'renamed-file.dat' 
});

// Filename detection from content-disposition header
await download('https://api.example.com/download/123', 'downloads');

Archive Extraction

// Extract zip/tar/etc archives
await download('https://example.com/archive.zip', 'extracted', { 
  extract: true 
});

// Extract with decompress options
await download('https://example.com/archive.tar.gz', 'output', {
  extract: true,
  strip: 1  // decompress option - remove one level of directories
});

HTTP Configuration

// Custom headers
await download('https://api.example.com/file', 'downloads', {
  headers: {
    'Authorization': 'Bearer token123',
    'User-Agent': 'MyApp/1.0'
  }
});

// Proxy support
await download('https://example.com/file.zip', 'downloads', {
  proxy: 'http://proxy.example.com:8080'
});

// SSL configuration
await download('https://untrusted-ssl.example.com/file', 'downloads', {
  rejectUnauthorized: false
});

Batch Downloads

// Download multiple files
await Promise.all([
  'https://example.com/file1.jpg',
  'https://example.com/file2.png',
  'https://example.com/file3.gif'
].map(url => download(url, 'downloads')));

// Download with different options
const downloads = [
  { url: 'https://example.com/doc.pdf', dest: 'documents' },
  { url: 'https://example.com/archive.zip', dest: 'archives', extract: true }
];

await Promise.all(downloads.map(({ url, dest, ...opts }) => 
  download(url, dest, opts)
));

Error Handling

// HTTP errors (404, 500, etc.)
try {
  await download('https://example.com/nonexistent');
} catch (error) {
  if (error.response?.statusCode === 404) {
    console.log('File not found');
  }
}

// Network errors
try {
  await download('https://unreachable-server.com/file');
} catch (error) {
  if (error.code === 'ENOTFOUND') {
    console.log('Server not found');
  }
}

// File system errors (permissions, disk space, etc.)
try {
  await download('https://example.com/file', '/read-only-directory');
} catch (error) {
  if (error.code === 'EACCES') {
    console.log('Permission denied');
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-download
Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/download@8.0.x
Publish Source
CLI
Badge
tessl/npm-download badge