How to Load a Module in Perl (use, require, @INC, and Best Practices)
Question
perl how do you load a module
Difficulty: Beginner (with intermediate/advanced notes)
Tags: perl, modules, use, require, import, @INC, PERL5LIB, cpan
What “loading a module” means in Perl
In Perl, a module is typically a reusable library packaged as a .pm file that defines a package. “Loading a module” usually means:
- Finding the module file on disk (e.g.,
Time/Piece.pmforTime::Piece) using Perl’s module search path (@INC). - Reading and compiling that file (so the module’s code becomes available).
- Optionally importing symbols (functions/variables) from the module into your namespace (usually your script’s
mainpackage).
A common confusion: loading a module is not the same as installing it. Installation (via CPAN, your OS package manager, or cpanm) puts the module file somewhere on disk. Loading is what your program does at runtime/compile time to use it.
The module search path: @INC
When you say use Some::Module; or require Some::Module;, Perl searches directories listed in @INC. Conceptually, Perl turns the module name into a path:
Some::Module→Some/Module.pm
If Perl cannot find that .pm file in any @INC directory, you’ll see an error like “Can’t locate Some/Module.pm in @INC …”.
How @INC gets populated: it’s built from Perl’s compiled-in library paths, plus environment variables like PERL5LIB, plus any -I include paths you pass on the command line, plus anything you add at runtime (e.g., via use lib or unshift @INC, ...).
The two main ways to load modules: use vs require
use Module; (compile-time load + import)
use is the most common and recommended way for typical dependencies. It happens at compile time (in a BEGIN phase), and it usually imports symbols into your namespace.
Roughly, Perl treats this:
use Some::Module qw(foo bar);
as if you wrote something like this (simplified):
BEGIN {
require Some::Module;
Some::Module->import(qw(foo bar));
}
This explains two important behaviors:
- The module is loaded early, before runtime statements execute.
- Import happens automatically unless you prevent it.
require Module; (runtime load, no automatic import)
require loads a module at runtime (when execution reaches that line). It does not automatically import symbols. If you want imports, you call import yourself:
require Some::Module;
Some::Module->import(qw(foo));
require is useful for:
- Optional dependencies (try to load, but keep running if missing).
- Plugin systems (load modules based on config/user input).
- Reducing startup time (load heavy modules only if a feature is used).
Example 1: Loading a core module with use
This example uses a core module (Time::Piece) and prints a deterministic date using gmtime(0) (the Unix epoch).
#!/usr/bin/env perl
use strict;
use warnings;
use Time::Piece;
my $t = gmtime(0);
print $t->ymd, "\n";
Expected output:
1970-01-01
What to notice: you didn’t need to mention .pm or paths. Perl found Time/Piece.pm somewhere in @INC, loaded it, and then you used its methods.
Example 2: Loading your own module from a custom path
Real projects often have local modules that aren’t installed system-wide. Common approaches are:
- Put your module under a project
lib/directory and add it viause lib 'lib'; - Set
PERL5LIBor pass-Ion the command line
The example below is fully runnable as a single script: it creates a temporary My/Greeter.pm, adds the temp lib directory to @INC, then loads the module and calls it. It uses a BEGIN block to ensure the file exists before use My::Greeter; runs (because use is compile-time).
#!/usr/bin/env perl
use strict;
use warnings;
BEGIN {
require File::Temp;
require File::Path;
my $tmp = File::Temp::tempdir(CLEANUP => 1);
my $lib = "$tmp/lib";
File::Path::make_path("$lib/My");
open my $fh, ">", "$lib/My/Greeter.pm" or die "open module: $!";
print {$fh} <<'PM';
package My::Greeter;
use strict;
use warnings;
sub greet {
my ($name) = @_;
return "Hello, $name!";
}
1;
PM
close $fh or die "close module: $!";
unshift @INC, $lib;
}
use My::Greeter;
print My::Greeter::greet("Ada"), "\n";
Expected output:
Hello, Ada!
Key takeaways:
- Module name
My::Greetermaps toMy/Greeter.pm. - Adding a directory to
@INC(or usinguse lib) is how Perl finds non-installed modules. - Modules must return a true value at the end (commonly
1;), orrequire/usewill fail.
Example 3: Conditional loading with require (optional dependency pattern)
This pattern is common in production: try to load something, but don’t crash if it’s not there. Then fall back to something else, or disable a feature.
#!/usr/bin/env perl
use strict;
use warnings;
my $missing = "This::Module::Does::Not::Exist";
my $ok = eval "require $missing; 1";
print "try_missing_ok=", ($ok ? 1 : 0), "\n";
print "missing_error_present=", ($@ ? 1 : 0), "\n";
my $fallback = "Data::Dumper"; # core module
my $ok2 = eval "require $fallback; 1";
die "failed to load fallback: $@" if !$ok2;
print "fallback_ok=1\n";
Expected output:
try_missing_ok=0
missing_error_present=1
fallback_ok=1
Notes: Using string eval is one way to require a module whose name is in a variable. In modern Perl ecosystems, you’ll often see CPAN utilities like Module::Runtime or Module::Load used to do this more safely (they help validate module names and avoid accidental code injection if the module name comes from untrusted input).
Imports, versions, and loading without importing
Import lists
Many modules export functions (e.g., List::Util exports sum if requested). Prefer importing only what you use:
use List::Util qw(sum);
print sum(1, 2, 3), "\n";
Importing everything (if a module allows it) can cause naming collisions and make code harder to read.
Load a module but do not import anything
Sometimes you want the module loaded but you prefer calling fully-qualified names (or the module exports too much). Use empty parentheses:
use Some::Module ();
This loads the module but calls import with an empty list, effectively importing nothing.
Version checks
You can request a minimum module version when loading:
use Some::Module 1.23;
If the installed module is older, Perl errors early. This is a best practice for APIs that changed over time. Similarly, you can require a minimum Perl version:
use 5.010;
Ways to add module search paths (real-world project setup)
use lib 'path';— adds a directory to@INC(compile-time). Common in scripts:use FindBin; use lib "$FindBin::Bin/../lib";perl -Ilib script.pl— addslib/to@INCfor that invocation (great for tooling and CI).PERL5LIB=/path/to/lib— environment variable for include paths (useful for dev shells; be careful in production because it can hide missing dependency problems).local::lib— a standard way to install CPAN modules into a user-local directory and set up environment variables accordingly (common on servers without root access).
Best practices
- Prefer
usefor normal dependencies: it fails early and keeps dependency loading predictable. - Import sparingly:
use Module qw(needed_function);instead of importing everything. - Use
use Module ();when you don’t want exports: keeps your namespace clean. - Pin minimum versions for modules with changing APIs:
use DBI 1.643;(example). - For optional/dynamic loads, prefer safe patterns: validate module names if they come from config/user input; consider CPAN helpers (
Module::Runtime) in larger systems. - Keep project-local modules in a
lib/directory and add it via-Ioruse librather than editing global Perl installs.
Common pitfalls (and how to avoid them)
- Forgetting
1;at the end of a module:require/useexpects the file to return true. - Mismatch between package name and file path:
My::Thingshould live atMy/Thing.pm(relative to an@INCdirectory). - Trying to do
useinside runtime conditionals:useruns at compile time, soif ($x) { use Foo; }won’t behave like you think. Userequire+importfor conditional loading. - Expecting
requireto import functions: it won’t unless you callimportyourself. - Confusing
do 'file.pl'with module loading:doloads a file by path, not by module name-to-path mapping, and it has different error/return semantics. Preferrequire Modulefor modules. - Shadowed modules due to
@INCorder: Perl uses the first match. Accidentally putting an oldlib/early in@INCcan load the wrong version. - Debugging “Can’t locate … in @INC”: print
@INCand verify your include paths; confirm the file exists at the expected path.
Real-world usage patterns
- Web apps / services: load core dependencies with
useat the top for fast failure; load optional integrations (metrics, tracing, extra codecs) withrequireonly when configured. - CLI tools: keep startup snappy by deferring heavy modules until a subcommand needs them.
- Plugin architectures: read a list of plugin module names from config and
requirethem at runtime; verify module names against an allowlist. - Multi-environment deployments: use
local::libor vendored dependencies; avoid relying on global system Perl library paths differing across servers.
Quick checklist
- Installed? (CPAN/OS packages) — then load with
use. - Local module? Put it under
lib/and add-Iliboruse lib. - Need conditional loading? Use
require(and optionallyimport). - Need no exports?
use Module ();. - Need a minimum version?
use Module 1.23;.
Verified Code
Executed in a sandbox to capture real output. • 25ms
Hello, Ada!
(empty)Was this helpful?
Related Questions
- How to Write to a File in Perl (open/print, modes, safety, and best practices)
- How to Run Perl Code on macOS (Terminal, Scripts, Shebangs, Modules, and Common Pitfalls)
- How to Add Elements to an Array in Perl (push, unshift, splice, indexing, and arrayrefs)
- How to Install Perl Modules on Windows (CPAN, cpanm, Strawberry Perl, ActiveState, local::lib)
- How to Compare Strings in Perl (eq/ne, lt/gt, cmp, case-insensitive, Unicode)
- How to Check If a Perl Module Is Installed (and Loadable)