Skip to main content

How to Get a CPAN Module Download URL

·349 words·2 mins·
metacpan perl
Table of Contents
❀️ It's great to see you here! I'm currently available on evenings and weekends for consulting and freelance work. Let's chat about how I can help you achieve your goals.

Every so often you find yourself requiring the download URL for a CPAN module. You can use the MetaCPAN API to do this quite easily, but depending on your use case, you may not be able to do this in a single query. Well, that’s actually not entirely true. Now that we have v1 of the MetaCPAN API deployed, you can test out the shiny new (experimental) download_url endpoint. This was an endpoint added by Clinton Gormley at the QA Hackathon in Berlin. Its primary purpose is to make it easy for an app like cpanm to figure out which archive to download when a module needs to be installed. MetaCPAN::Client doesn’t support this new endpoint yet, but if you want to take advantage of it, it’s pretty easy.

use strict;
use warnings;
use feature qw( say );

use Cpanel::JSON::XS qw( decode_json );
use LWP::UserAgent;
use URI::FromHash qw( uri );

my $module = shift @ARGV;

my $ua  = LWP::UserAgent->new;
my $uri = uri(
    scheme => 'https',
    host   => '',
    path   => '/v1/download_url/' . $module,

my $res = $ua->get($uri);
say decode_json( $res->decoded_content )->{download_url};

Now invoke your script:

$ perl Plack


After I originally wrote this post, MICKEY stepped up and actually added the functionality to MetaCPAN::Client. A huge thank you to him for doing this. πŸ™‚ Let’s try this again:

use strict;
use warnings;
use feature qw( say );

use MetaCPAN::Client 1.018000;
my $mcpan = MetaCPAN::Client->new( version => 'v1' );

my $module = shift @ARGV;

say $mcpan->download_url( $module )->download_url;

That cuts the lines of code almost in half and is less error prone than crafting the query ourselves. I’d encourage you to use MetaCPAN::Client unless you have a compelling reason not to.


This endpoint is experimental. Β It might not do what you want in all cases. Β See this GitHub issue for reference. Β Please add to this issue if you find more cases which need to be addressed. Β Having said that, this endpoint should do the right thing for most cases. Β Feel free to play with it to see if it suits your needs.


How I Spent my 2015 Hackathon
·650 words·4 mins
metacpan perl Programming
I’ll be at the 2015 New York Perl Hackathon
·157 words·1 min
metacpan perl Programming
How I Spent My 2015 Perl QA Hackathon
·2580 words·13 mins
metacpan perl Programming Perl Toolchain Summit