> For the complete documentation index, see [llms.txt](https://eth-limo.gitbook.io/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eth-limo.gitbook.io/documentation/advanced/alternatives-to-ipfs.md).

# Alternatives to IPFS

While IPFS is a popular choice for dWebsites, there are several other decentralized storage solutions that offer different trade-offs in terms of permanence, cost, and features. This guide explores the major alternatives and how to integrate them with ENS.

## Overview of Decentralized Storage Solutions

| Solution                       | Permanence                | Cost Model                | Primary Use Case            |
| ------------------------------ | ------------------------- | ------------------------- | --------------------------- |
| IPFS                           | Temporary (unless pinned) | Free (with pinning costs) | Content distribution        |
| Arweave                        | Permanent                 | One-time payment          | Permanent storage           |
| Swarm                          | Temporary                 | Free                      | Web3 infrastructure         |
| On-chain Data URLs (ENS hooks) | Permanent (on-chain)      | Gas per byte              | Small, high-value artifacts |
| Filecoin                       | Permanent                 | Ongoing rental            | IPFS incentivization        |

## Arweave

Arweave provides permanent, decentralized storage with a one-time payment model.

### Key Features

* **Permanent Storage**: Content is stored forever with a single payment
* **Proof of Access**: Novel consensus mechanism ensures data availability
* **Endowment Model**: One-time payment covers indefinite storage
* **Fast Retrieval**: Optimized for quick content access

### Getting Started with Arweave

#### 1. Install Arweave Tools

```bash
# Install arweave-js
npm install arweave

# Or use the Arweave CLI
npm install -g arweave-cli
```

#### 2. Create a Wallet

```javascript
import Arweave from 'arweave';

const arweave = Arweave.init({
    host: 'arweave.net',
    port: 443,
    protocol: 'https'
});

// Generate a new wallet
const wallet = await arweave.wallets.generate();
const address = await arweave.wallets.jwkToAddress(wallet);

console.log('Wallet address:', address);
```

#### 3. Upload Content

```javascript
// Upload a file to Arweave
async function uploadToArweave(filePath, wallet) {
    const data = await fs.readFile(filePath);
    
    const transaction = await arweave.createTransaction({
        data: data
    }, wallet);
    
    // Add tags for better organization
    transaction.addTag('Content-Type', 'text/html');
    transaction.addTag('App-Name', 'dWebsite');
    
    await arweave.transactions.sign(transaction);
    const response = await arweave.transactions.post(transaction);
    
    return transaction.id;
}

// Upload website files
const websiteFiles = ['index.html', 'style.css', 'script.js'];
const uploadPromises = websiteFiles.map(file => 
    uploadToArweave(`./website/${file}`, wallet)
);

const transactionIds = await Promise.all(uploadPromises);
console.log('Uploaded files:', transactionIds);
```

#### 4. Integrate with ENS

```javascript
// Set Arweave content hash in ENS
async function setArweaveContenthash(domain, arweaveId) {
    const resolver = new ethers.Contract(resolverAddress, RESOLVER_ABI, signer);
    const node = ethers.utils.namehash(domain);
    
    // Encode Arweave ID for contenthash
    const encoded = ethers.utils.hexlify(
        ethers.utils.concat([
            0x6b, // Arweave multicodec
            ethers.utils.toUtf8Bytes(arweaveId)
        ])
    );
    
    await resolver.setContenthash(node, encoded);
}

// Example usage
await setArweaveContenthash('mydomain.eth', 'arweave-transaction-id');
```

### Arweave Best Practices

* **Bundle Multiple Files**: Use Arweave's bundling feature for multiple files
* **Set Appropriate Tags**: Use tags for better content organization
* **Consider Costs**: Calculate storage costs before uploading large files
* **Backup Wallets**: Securely store your Arweave wallet

## Swarm

Swarm is Ethereum's native storage layer, designed to work seamlessly with the Ethereum ecosystem.

### Key Features

* **Ethereum Native**: Built specifically for Ethereum
* **Incentivized Storage**: Nodes earn rewards for storing data
* **Automatic Replication**: Data is automatically distributed across nodes
* **Privacy Features**: Built-in encryption and privacy controls

### Getting Started with Swarm

#### 1. Install Swarm

```bash
# Download Swarm binary
wget https://github.com/ethersphere/bee/releases/latest/download/bee-linux-amd64

# Make executable
chmod +x bee-linux-amd64

# Move to PATH
sudo mv bee-linux-amd64 /usr/local/bin/bee
```

#### 2. Start a Swarm Node

```bash
# Initialize Swarm node
bee init

# Start the node
bee start
```

#### 3. Upload Content

```bash
# Upload a single file
bee upload ./website/index.html

# Upload a directory
bee upload ./website/

# Get the Swarm hash
SWARM_HASH=$(bee upload ./website/ | grep -o '^[a-f0-9]\{64\}$')
echo "Swarm hash: $SWARM_HASH"
```

#### 4. JavaScript Integration

```javascript
import { Bee } from '@ethersphere/bee-js';

const bee = new Bee('http://localhost:1633');

// Note: Verify Swarm Bee version and API compatibility
// Check: https://docs.ethswarm.org/docs/

// Upload file
async function uploadToSwarm(file) {
    const fileData = await file.arrayBuffer();
    const result = await bee.uploadData(fileData);
    return result.reference;
}

// Upload directory
async function uploadDirectory(files) {
    const result = await bee.uploadFiles(files);
    return result.reference;
}
```

See [Hosting on Swarm](/documentation/swarm/hosting-on-swarm.md) for the full publishing guide, including the managed Beeport interface.

#### 5. ENS Integration

```javascript
// Set Swarm content hash in ENS
async function setSwarmContenthash(domain, swarmHash) {
    const resolver = new ethers.Contract(resolverAddress, RESOLVER_ABI, signer);
    const node = ethers.utils.namehash(domain);
    
    // Encode Swarm hash for contenthash
    const encoded = ethers.utils.hexlify(
        ethers.utils.concat([
            0x7b, // Swarm multicodec
            ethers.utils.hexToBytes(swarmHash)
        ])
    );
    
    await resolver.setContenthash(node, encoded);
}
```

## On-Chain Data URLs (ENS Hooks)

Rather than referencing a storage network at all, content can be stored directly on chain and served from a smart contract via an [EIP-8121](https://ethereum-magicians.org/t/erc-8121-delegated-metadata-resolution-via-hooks/27424) hook in the ENS contenthash.

### Key Features

* **No Storage Network**: The blockchain is the storage layer — no pinning, deals, or postage stamps
* **Self-Describing Resolution**: The contenthash specifies the exact contract call (function, parameters, contract, chain) that returns the content
* **Cross-Chain**: Content can live on any EVM chain, resolved via CCIP-Read (ERC-3668)
* **Updatable**: Change the contract's stored data without touching the contenthash
* **Size-Constrained**: Gas pricing makes it practical only for small artifacts (\~5KB or less)

See [On-Chain Data URLs and ENS Hooks](/documentation/advanced/onchain-data-urls.md) for the concepts, and the [ens-hooks encoding guide](https://github.com/ethlimo/ens-hooks/blob/main/docs/guide.md) for a publishing walkthrough.

## Filecoin

Filecoin is a decentralized storage network that incentivizes IPFS storage.

### Key Features

* **IPFS Compatible**: Built on top of IPFS — content is addressed by the same CIDs
* **Incentivized Storage**: Storage providers earn FIL for provably storing data
* **Proof of Storage**: Cryptographic proofs ensure data availability
* **Marketplace**: Dynamic pricing based on supply and demand

### Getting Started with Filecoin Pin

The most direct path for dWebsites is [Filecoin Pin](https://docs.filecoin.io/build-on-filecoin/cookbook/filecoin-pin/getting-started), which combines Filecoin's paid, provable storage with standard IPFS retrieval: you pin a file to Filecoin and fetch it with ordinary IPFS tooling — so the resulting Root CID works as an `ipfs://` ENS content hash.

You'll need an Ethereum-style wallet, FIL for gas, and USDFC (a stablecoin) for storage payments.

```bash
# Install and verify
npm install -g filecoin-pin@latest
filecoin-pin --version

# Authorize spending and deposit USDFC (~10 USDFC to start)
filecoin-pin payments setup

# Pin content — stored with two providers for redundancy, returns a Root CID
filecoin-pin add ./my-site

# Verify storage proofs and payment status
filecoin-pin data-set list
filecoin-pin payments status
```

Retrieve the Root CID through any IPFS gateway, and set it as your ENS content hash (`ipfs://<root-cid>`) like any other IPFS deployment.

## Comparison and Selection Guide

### When to Use Each Solution

#### Choose IPFS when:

* You need temporary content distribution
* You want to avoid ongoing costs
* You're building a content-heavy application
* You need fast content discovery

#### Choose Arweave when:

* You need permanent storage
* You want predictable one-time costs
* You're building applications that require data permanence
* You need fast retrieval times

#### Choose Swarm when:

* You're building Ethereum-native applications
* You want automatic data replication
* You need privacy features
* You want to contribute to Ethereum's storage layer

#### Choose On-Chain Data URLs (ENS hooks) when:

* Your artifact is small (roughly 5KB or less)
* You want availability tied only to the chain itself — no pinning or renewal
* You need to update content by changing contract state
* Your data is already on chain or needs cross-chain resolution (credentials, registries, metadata)

#### Choose Filecoin when:

* You want IPFS with economic incentives
* You need verifiable storage proofs
* You want to participate in the storage marketplace
* You need enterprise-grade storage guarantees

## Multi-Protocol Strategies

### Fallback Systems

```javascript
class MultiProtocolStorage {
    constructor() {
        this.protocols = {
            ipfs: new IPFSClient(),
            arweave: new ArweaveClient(),
            swarm: new SwarmClient()
        };
    }
    
    async uploadWithFallback(content, primaryProtocol = 'ipfs') {
        try {
            // Try primary protocol
            return await this.protocols[primaryProtocol].upload(content);
        } catch (error) {
            console.log(`Primary protocol failed, trying fallbacks...`);
            
            // Try fallback protocols
            for (const [protocol, client] of Object.entries(this.protocols)) {
                if (protocol !== primaryProtocol) {
                    try {
                        return await client.upload(content);
                    } catch (fallbackError) {
                        console.log(`${protocol} failed:`, fallbackError.message);
                    }
                }
            }
            
            throw new Error('All protocols failed');
        }
    }
}
```

### ENS Multi-Protocol Support

```javascript
// Set multiple protocol references in ENS
async function setMultiProtocolContent(domain, contentRefs) {
    const resolver = new ethers.Contract(resolverAddress, RESOLVER_ABI, signer);
    const node = ethers.utils.namehash(domain);
    
    // Set primary contenthash
    if (contentRefs.ipfs) {
        const encoded = encodeIPFSContenthash(contentRefs.ipfs);
        await resolver.setContenthash(node, encoded);
    }
    
    // Set fallback protocols as TXT records
    if (contentRefs.arweave) {
        await resolver.setText(node, 'arweave', contentRefs.arweave);
    }
    
    if (contentRefs.swarm) {
        await resolver.setText(node, 'swarm', contentRefs.swarm);
    }
}
```

## Cost Analysis

### Storage Costs Comparison

| Protocol | Cost Model          | Example Cost (1GB/month) |
| -------- | ------------------- | ------------------------ |
| IPFS     | Free (with pinning) | $5-20 (pinning service)  |
| Arweave  | One-time            | $0.50-1.00 (permanent)   |
| Swarm    | Free                | $0 (incentivized)        |
| Filecoin | Market rate         | $1-3/month               |

### Cost Optimization Strategies

1. **Hybrid Approach**: Use IPFS for temporary content, Arweave for permanent
2. **Compression**: Compress content before uploading
3. **Deduplication**: Avoid storing duplicate content
4. **Selective Storage**: Store only essential content permanently

## Best Practices

### 1. Protocol Selection

* **Evaluate Requirements**: Consider permanence, cost, and performance needs
* **Test Multiple Protocols**: Try different solutions before committing
* **Monitor Costs**: Track storage costs across protocols
* **Plan for Migration**: Design systems that can migrate between protocols

### 2. Content Management

* **Version Control**: Implement versioning for content updates
* **Backup Strategy**: Use multiple protocols for redundancy
* **Content Optimization**: Optimize file sizes and formats
* **Metadata Management**: Maintain proper content metadata

### 3. Integration Patterns

* **Abstraction Layer**: Build abstraction layers for protocol switching
* **Fallback Mechanisms**: Implement automatic fallbacks
* **Monitoring**: Monitor content availability across protocols
* **User Experience**: Ensure seamless experience regardless of protocol

## Tools and Resources

### Development Tools

* [Arweave JS](https://github.com/ArweaveTeam/arweave-js)
* [Swarm Bee](https://github.com/ethersphere/bee)
* [Filecoin Pin](https://docs.filecoin.io/build-on-filecoin/cookbook/filecoin-pin/getting-started)

### Documentation

* [Arweave Documentation](https://docs.arweave.org/)
* [Swarm Documentation](https://docs.ethswarm.org/)
* [Filecoin Documentation](https://docs.filecoin.io/)

## Next Steps

With knowledge of storage alternatives, explore:

* [Arweave and ArNS](/documentation/advanced/arweave-arns.md) - Deep dive into permanent storage
* [On-Chain Data URLs and ENS Hooks](/documentation/advanced/onchain-data-urls.md) - Serving content directly from smart contracts
* [ENS Subdomains and CCIP](/documentation/advanced/ens-subdomains-ccip.md) - Advanced ENS features
* [Record Types](/documentation/advanced/record-types.md) - Understanding ENS record systems
