Skip to main content

curseforge-dl

A Python package to download mods, resource packs, and shader packs from CurseForge. Replicates the download logic used by HMCL.

Installation

pip install curseforge-dl

Usage

CLI

# Set your CurseForge API key (choose one method):

# Method 1: Create a .env file (recommended)
cp .env.example .env
# Edit .env and set CURSEFORGE_API_KEY=your-key

# Method 2: Environment variable
export CURSEFORGE_API_KEY="your-api-key"

# Method 3: Pass directly via CLI
curseforge-dl --api-key "your-api-key" install modpack.zip ./output

# Fetch modpack info by slug
curseforge-dl fetch all-the-mods-10

# Download latest modpack zip by slug
curseforge-dl download all-the-mods-10 --output-dir ./downloads

# Download with Minecraft version filter
curseforge-dl download all-the-mods-10 -g 1.21.1 -o ./downloads

# Install a CurseForge modpack
curseforge-dl install modpack.zip ./output

# Search for mods
curseforge-dl search "JEI" --game-version 1.21.1

# Get mod info
curseforge-dl info 238222

# Parse modpack info (no API key / download needed)
curseforge-dl modpack-info modpack.zip

# Parse modpack info with full mod list
curseforge-dl modpack-info modpack.zip --show-mods

Python API

import asyncio
from curseforge_dl import CurseForgeAPI, ModpackInstaller

async def main():
    async with CurseForgeAPI(api_key="your-key") as api:
        # Search mods
        results = await api.search_mods("JEI", game_version="1.21.1")
        for mod in results:
            print(mod.name)

        # Find a modpack by slug
        modpack = await api.get_mod_by_slug("all-the-mods-10", class_id=4471)
        if modpack:
            print(f"{modpack.name}{modpack.download_count:,} downloads")

        # Download latest modpack zip by slug
        installer = ModpackInstaller(api)
        zip_path, addon, file = await installer.download_modpack_by_slug(
            "all-the-mods-10", output_dir="./downloads"
        )
        print(f"Downloaded {addon.name} to {zip_path}")

        # Install a modpack from zip
        await installer.install("modpack.zip", "./output")

asyncio.run(main())

Parse modpack info (no API key needed)

from curseforge_dl import ModpackInstaller

manifest = ModpackInstaller.parse_modpack_info("modpack.zip")

print(manifest.name)                          # "All the Mods 10"
print(manifest.version)                       # "5.5"
print(manifest.author)                        # "ATMTeam"
print(manifest.minecraft.version)             # "1.21.1"

for loader in manifest.minecraft.mod_loaders:
    print(loader.id)                          # "neoforge-21.1.219"

print(f"Total mods: {len(manifest.files)}")   # 480

Features

  • Modpack fetch by slug: Look up any modpack by its slug and view latest version info
  • Modpack download by slug: Download the latest modpack zip directly by slug
  • Modpack installation: Parse CurseForge modpack zips and download all mods
  • Modpack info: Parse modpack metadata (MC version, loader, mod list) without downloading
  • Smart URL construction: Falls back to CDN URL when API doesn't provide download links
  • File fingerprinting: MurmurHash2-based local file matching
  • Async downloads: Parallel downloads with configurable concurrency
  • Download retry: Automatic retry with exponential backoff on failure (default 3 attempts)
  • Progress reporting: Built-in tqdm progress bars

License

MIT

Release files for curseforge-dl 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for curseforge-dl 1.2.0
File Size Uploaded
curseforge_dl-1.2.0.tar.gz 40.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for curseforge-dl 1.2.0
File Interpreter ABI Platform
curseforge_dl-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 58.9 kB

Release files / curseforge_dl-1.2.0.tar.gz

Download URL curseforge_dl-1.2.0.tar.gz
Size 40.5 kB
Tags Source
SHA-256 checksum
How to use checksums
968fd3dd0161f9dd0821e2232ff88c4093b0ea8138bd19c7a69ab22380af7f69
BLAKE2b-256 checksum
How to use checksums
88faa204f240d00853448657eea5e8a6103fa5bc47fe554e274ac25e46ca2356
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 25, 2026.

Transparency log

Release files / curseforge_dl-1.2.0-py3-none-any.whl

Download URL curseforge_dl-1.2.0-py3-none-any.whl
Size 18.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8a99e95f350dc8145a49de43e8fdfbb3a24b16067e3710da9d486701e8f2c55a
BLAKE2b-256 checksum
How to use checksums
b55ac20efec781c9758fd06366d25e1bb4bd47cfa9568e2af9279cfe31f92a10
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Feb 25, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page