Perl beginner

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.pm for Time::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 main package).

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::ModuleSome/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 via use lib 'lib';
  • Set PERL5LIB or pass -I on 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::Greeter maps to My/Greeter.pm.
  • Adding a directory to @INC (or using use lib) is how Perl finds non-installed modules.
  • Modules must return a true value at the end (commonly 1;), or require/use will 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 — adds lib/ to @INC for 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 use for 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 -I or use lib rather than editing global Perl installs.

Common pitfalls (and how to avoid them)

  • Forgetting 1; at the end of a module: require/use expects the file to return true.
  • Mismatch between package name and file path: My::Thing should live at My/Thing.pm (relative to an @INC directory).
  • Trying to do use inside runtime conditionals: use runs at compile time, so if ($x) { use Foo; } won’t behave like you think. Use require + import for conditional loading.
  • Expecting require to import functions: it won’t unless you call import yourself.
  • Confusing do 'file.pl' with module loading: do loads a file by path, not by module name-to-path mapping, and it has different error/return semantics. Prefer require Module for modules.
  • Shadowed modules due to @INC order: Perl uses the first match. Accidentally putting an old lib/ early in @INC can load the wrong version.
  • Debugging “Can’t locate … in @INC”: print @INC and verify your include paths; confirm the file exists at the expected path.

Real-world usage patterns

  • Web apps / services: load core dependencies with use at the top for fast failure; load optional integrations (metrics, tracing, extra codecs) with require only 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 require them at runtime; verify module names against an allowlist.
  • Multi-environment deployments: use local::lib or 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 -Ilib or use lib.
  • Need conditional loading? Use require (and optionally import).
  • Need no exports? use Module ();.
  • Need a minimum version? use Module 1.23;.

Verified Code

Executed in a sandbox to capture real output. • 25ms

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
Hello, Ada!
STDERR
(empty)

Was this helpful?

Related Questions