# dler

> Smart and easy-to-use fetch-based downloader for Node.js compatible runtimes

Latest version **0.8.0** (published 2025-06-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install dler
pnpm add dler
yarn add dler
bun add dler
```

Provides the command `dler`.

## Health

**Score 50/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads; pre 1.0.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 0.8.0 |
| Published | 2025-06-22 |
| First published | 2020-08-08 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=17.5.0 |
| Dependencies | 0 |
| Unpacked size | 20 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | YieldRay |
| Maintainers | yieldray |
| Keywords | download |

## Links

- npm: https://www.npmjs.com/package/dler
- Repository: https://github.com/YieldRay/dler
- Homepage: https://github.com/YieldRay/dler#readme
- Issues: https://github.com/YieldRay/dler/issues
- npm.io page: https://npm.io/package/dler

## Recent versions

- 0.8.0 (latest) — 2025-06-22
- 0.7.3 — 2025-06-03
- 0.7.2 — 2024-10-02
- 0.7.1 — 2024-06-02
- 0.7.0 — 2024-06-01
- 0.6.1 — 2023-12-27
- 0.6.0 — 2023-10-08
- 0.5.0 — 2023-07-22
- 0.4.4 — 2023-03-04
- 0.4.3 — 2023-03-04
- 0.4.1 — 2023-03-02
- 0.4.0 — 2023-03-02
- 0.3.2 — 2023-02-17
- 0.3.1 — 2023-02-17
- 0.3.0 — 2023-01-18
- … 13 more at https://npm.io/package/dler/versions

## README

# dler

[![](https://badgen.net/packagephobia/install/dler)](https://packagephobia.com/result?p=dler)
[![](https://img.shields.io/npm/v/dler)](https://www.npmjs.com/package/dler)  
Smart and easy-to-use `fetch`-based downloader for Node.js compatible runtimes.

> [!IMPORTANT]  
> `dler` is ESM only, and since it uses the built-in `fetch`, it requires `nodejs>=17.5.0`.

## Features

-   Automatically detect the download file name.
-   Bing your own `fetch`.
-   Dependency free.
-   Supports resuming downloads.

## Limitations

-   Does not support multi-threaded or segmented downloads; only sequential downloads are supported.
-   Proxy support depends on the runtime's implementation of the `fetch` function. For example, Deno supports [automatic proxy](https://docs.deno.com/api/deno/fetch), while Node.js and Bun do not.  
    However, this can be addressed by customizing the `fetch` function.

## Installation

```sh
$ npm install dler
```

## Usage

```js
import { download } from 'dler';

const url = 'https://api.ip.sb/ip';

// simple
download(url, './ipinfo.txt');

// auto detect file name
download(url);
download(url, 'dirname/');

// with options
download(url, {
    filePath: 'dirname/',
    onProgress: (receivedLength, totalLength) => {
        if (totalLength) console.log((100 * (receivedLength / totalLength)).toFixed(2) + '%');
    },
    onReady: (resp, saveAs) => console.log(`Downloading ${resp.url} to ${saveAs}`),
    /* other options in RequestInit */
    headers: {
        Authorization: 'Bearer xxx',
    },
    signal: AbortSignal.timeout(1000),
});
```

```js
// use promise
download(url [,options]).then(path => console.log(`File saved to ${path}`));

// use async/await
const absolutePath = await download(url [,options]);
```

```ts
/**
 * Interface representing the initialization options for the downloader.
 * Extends the `RequestInit` interface.
 *
 * Boolean options default to `false` if not specified.
 */
interface DlerInit extends RequestInit {
    /**
     * Optional file path where the downloaded file will be saved.
     * If not provided or if provided as a string ending with '/', the file name will be derived from
     * the `Content-Disposition` header or the basename of the final (maybe redirected) requested URL.
     */
    filePath?: string;

    /**
     * Flag to bypass the default check for HTTP status.
     * By default, the response is considered OK if `response.ok` is true.
     * Set this to `true` to disable this check.
     */
    doNotCheckOK?: boolean;

    /**
     * Flag to enable resuming the download if the file already exists.
     * By default, resumption is not attempted.
     * Set this to `true` to enable download resumption.
     * By default, resumption commences at the file size, which may not be desirable.
     * Specify a number to reset the starting range.
     */
    tryResumption?: boolean | number;

    /**
     * Callback function for monitoring download progress.
     * If `Content-Length` is not provided, `totalLength` will be set to `0`.
     *
     * @param receivedLength - The number of bytes received so far.
     * @param totalLength - The total number of bytes to be received.
     */
    onProgress?: (receivedLength?: number, totalLength?: number) => void;

    /**
     * Callback function invoked when the file is ready to be saved to disk.
     * If a string is returned, the file will be saved to the specified path.
     * This path overrides the `filePath` option.
     *
     * @param resp - The response object from the fetch request.
     * @param saveAs - Suggested file path for saving the file.
     * @returns A string representing the file path where the file should be saved, or a void/Promise resolving to such a string or void.
     */
    onReady?: (resp: Response, saveAs: string) => string | void | Promise<string | void>;
}
```

Use as a CLI tool (will log a progress bar in console).

```js
import { downloadInCLI } from 'dler';
const progressBarWidth = 50; // default value
await downloadInCLI(url, [options[, progressBarWidth]]);
```

Use as a global command.

```sh
$ npm i dler -g
$ dler --help
```

Bring your own `fetch` function.

```ts
import { downloadFromFetch } from 'dler';

const myFetch: typeof fetch = async (input, init) => {
    const res = await fetch(input, init);
    console.log(res); // do something...
    return res;
};

const path = await downloadFromFetch(myFetch, 'https://example.net/test.html', {
    filePath: './',
});
```

Use a ProxyAgent to make requests through a proxy server.

```ts
import { fetch as undiciFetch, ProxyAgent } from 'undici';

const myFetch = (url, options) => {
  return undiciFetch(url, {
    ...options,
    dispatcher: new ProxyAgent(<your_proxy_url>)
  })
}

downloadFromFetch(myFetch, 'https://example.net/test.html')
```

## Example

See `./test`

---
_Source: https://npm.io/package/dler · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
