# How to Use Swarm CLI for Uploading, Downloading, and Managing Files on Swarm

> Master Swarm CLI for effortless file uploads, downloads, and management on Swarm. Learn commands like upload, download, ls, pin, and delete to interact with your Bee node.

- Repository: [Ethersphere/awesome-swarm](https://github.com/ethersphere/awesome-swarm)
- Tags: how-to-guide
- Published: 2026-03-01

---

**Swarm CLI is a Go-based command-line wrapper around the Bee HTTP API that enables file uploads, downloads, and persistence management through subcommands like `upload`, `download`, `ls`, `pin`, and `delete` targeting a Bee node at `http://localhost:1633` by default.**

Swarm CLI serves as the official interface for the `ethersphere/swarm-cli` repository, eliminating the need to craft raw `curl` requests when interacting with the Swarm decentralized storage network. This tool handles the complexity of Mantaray manifest creation for directory structures and automatically manages required postage batch headers for storage persistence. Whether you are publishing static websites or archiving datasets, the CLI communicates with your local Bee node or any remote endpoint you specify.

## Uploading Files to Swarm

The `upload` command, implemented in [[`cmd/upload.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/upload.go)](https://github.com/ethersphere/swarm-cli/blob/main/cmd/upload.go), streams data to the Bee node's `/bytes` or `/bzz` endpoints. This subcommand supports both single-file uploads and recursive directory archiving with automatic manifest generation.

### Upload a Single File

To store an individual file and retrieve its Swarm reference (hash):

```bash
swarm upload ./document.pdf

```

The command returns a 64-character Swarm hash (e.g., `bzz/5e7f9a…`) that serves as the permanent content address. According to the source code, the CLI handles the HTTP POST request to the Bee API and extracts the reference from the response headers.

### Upload a Directory Recursively

For folder structures, the `--recursive` flag creates a Mantaray manifest that preserves the entire directory layout:

```bash
swarm upload --recursive ./website/

```

This generates a single root reference representing the folder, which you can later browse using the `ls` command or retrieve fully using `download` with the recursive flag.

## Downloading Files from Swarm

Implemented in [[`cmd/download.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/download.go)](https://github.com/ethersphere/swarm-cli/blob/main/cmd/download.go), the `download` command retrieves content via the `/bzz` endpoint. The CLI supports fetching both individual files and complete manifest trees.

### Download a Single File

Specify the Swarm hash and output path:

```bash
swarm download bzz/5e7f9a… -o ./downloaded.pdf

```

### Download a Full Directory

To restore an entire folder structure from a manifest reference, use the recursive flag:

```bash
swarm download bzz/9c3e4b… -r -o ./restored-folder/

```

The `-r` (or `--recursive`) flag instructs the CLI to traverse the manifest tree and recreate the original directory hierarchy locally, as implemented in the download logic.

## Listing Manifest Contents

The `ls` command, found in [[`cmd/ls.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/ls.go)](https://github.com/ethersphere/swarm-cli/blob/main/cmd/ls.go), displays the contents of a directory manifest without downloading the files. This is useful for verifying uploads before sharing references.

```bash
swarm ls bzz/9c3e4b…

```

Typical output displays a tree view:

```

📁 my-folder/
 ├─ 📄 file1.txt
 ├─ 📄 file2.png
 └─ 📁 subfolder/
      └─ 📄 nested.txt

```

This command queries the manifest metadata through the Bee API and formats the results for readability.

## Pinning References for Persistence

Pinning ensures your local Bee node retains specific content even during garbage collection. The pinning operations are implemented in [[`cmd/pin.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/pin.go)](https://github.com/ethersphere/swarm-cli/blob/main/cmd/pin.go), which interfaces with the Bee node's `/pins` endpoint.

### Pin a Reference

```bash
swarm pin add bzz/5e7f9a…

```

### Unpin a Reference

```bash
swarm pin rm bzz/5e7f9a…

```

You can view all currently pinned references with `swarm pin ls`. Pinning affects only the local node; it does not prevent other peers from caching or serving the content.

## Deleting Local Content

To remove a reference from your local node (unpinning and triggering garbage collection), use the `delete` command:

```bash
swarm delete bzz/5e7f9a…

```

**Important**: This operation only affects the **local** Bee node. Other network peers that have cached the data will continue to serve it until their own garbage collection cycles run.

## Configuration and Global Flags

The root command configuration in [[`cmd/root.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/root.go)](https://github.com/ethersphere/swarm-cli/blob/main/cmd/root.go) defines global flags available to all subcommands, while [[`internal/client.go`](https://github.com/ethersphere/awesome-swarm/blob/main/internal/client.go)](https://github.com/ethersphere/swarm-cli/blob/main/internal/client.go) implements the low-level HTTP client that manages API communication and injects the required `Swarm-Postage-Batch-Id` header when specified.

### Specify a Custom Gateway

By default, Swarm CLI targets `http://localhost:1633`. To use a remote Bee node or public gateway:

```bash
swarm upload ./data.bin --gateway https://gateway.example.com

```

### Postage Batch Management

Swarm requires postage batches for long-term storage. Provide an existing batch ID:

```bash
swarm upload ./data.bin --batch-id 0xabcdef1234567890...

```

If you omit `--batch-id` and the target Bee node has auto-batch functionality enabled, the CLI automatically requests a new postage stamp batch via the Bee `stamps` API before uploading.

## Summary

- **Swarm CLI** wraps the Bee HTTP API in simple subcommands, eliminating manual HTTP requests as implemented in `ethersphere/swarm-cli`.
- **Uploads** are handled by `swarm upload`, supporting both single files and recursive directory manifests via the Mantaray structure in [`cmd/upload.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/upload.go).
- **Downloads** use `swarm download` with the `-r` flag for recursive folder restoration via [`cmd/download.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/download.go).
- **Persistence** requires pinning via `swarm pin add` to prevent local garbage collection, implemented in [`cmd/pin.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/pin.go).
- **Global flags** `--gateway` and `--batch-id` in [`cmd/root.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/root.go) control node targeting and postage stamp assignment.

## Frequently Asked Questions

### Do I need a postage batch to upload files with Swarm CLI?

Yes, uploading requires a valid postage batch ID for the content to remain available on the network. You can specify one explicitly with `--batch-id`, or if your Bee node supports auto-batching, Swarm CLI will automatically request a new batch via the `stamps` API when the flag is omitted.

### What is the difference between uploading and pinning content?

Uploading stores data on the Swarm network and returns a reference hash, but the data may be garbage collected by your local node later. Pinning via `swarm pin add` tells your specific Bee node to retain that reference permanently, preventing automatic cleanup regardless of cache policies.

### Can I use Swarm CLI with a remote Bee node instead of localhost?

Absolutely. Use the `--gateway` flag to point to any accessible Bee endpoint. For example: `swarm upload ./file.txt --gateway https://remote-bee.example.com`. The underlying HTTP client in [`internal/client.go`](https://github.com/ethersphere/awesome-swarm/blob/main/internal/client.go) handles the connection and necessary header injection for any valid URL.

### How do I verify the contents of a folder before downloading it?

Use `swarm ls <hash>` to inspect the manifest structure. This command, implemented in [`cmd/ls.go`](https://github.com/ethersphere/awesome-swarm/blob/main/cmd/ls.go), displays a tree view of all files and subdirectories contained in the upload without transferring the actual file data, allowing you to confirm the reference contains the expected content.