How is Perl’s @INC constructed?

We will look at how the contents of this array are constructed and can be manipulated to affect where the Perl interpreter will find module files.

  1. Default @INC

The Perl interpreter is compiled with a specific default value for @INC. To find this value, run the command env -i perl -V (env -i ignores the PERL5LIB environment variable – see #2) and in the output you will see something like this:

$ env -i perl -V

Note the . at the end; this is the current directory (which is not necessarily the same as the script’s directory). It is missing in Perl 5.26+, and when Perl runs with -T (taint checks enabled).

To change the default path when configuring compilation of the Perl binary, set the configuration option otherlibdirs:

Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3

  1. Environment variable PERL5LIB (or PERLLIB)

Perl prepends a list of directories (colon-separated) contained in the PERL5LIB environment variable of your shell to @INC (if PERL5LIB is not defined, PERLLIB is used). To see the contents of @INC after the PERL5LIB and PERLLIB environment variables have taken effect, run perl -V:

$ perl -V
  1. -I command-line option

Perl prepends a list of directories (colon-separated) passed as the parameter of the -I command-line option to @INC. This can be done in three ways, as usual with Perl options:

  • Pass it on command line:

        perl -I /my/moduledir
  • Pass it via the first line (shebang) of your Perl script:

        #!/usr/local/bin/perl -w -I /my/moduledir
  • Pass it as part of the PERL5OPT (or PERLOPT) environment variable (see chapter 19.02 in Programming Perl)

  1. Pass it via the lib pragma

Perl prepends a list of directories passed in to it via use lib to @INC.

In a program:

    use lib ("/dir1", "/dir2");

On the command line:

    perl -Mlib=/dir1,/dir2

You can also remove the directories from @INC via no lib.

  1. You can directly manipulate @INC as a regular Perl array.

Note: Since @INC is used during the compilation phase, this must be done inside a BEGIN {} block, which precedes the use MyModule statement.

  • Add directories to the beginning via unshift @INC, $dir.

  • Add directories to the end via push @INC, $dir.

  • Do anything else you can do with a Perl array.

Note: The directories are unshifted onto @INC in the order listed in this answer, e.g. default @INC is last in the list, preceded by PERL5LIB, preceded by -I, preceded by use lib and direct @INC manipulation, the latter two mixed in whichever order they are in Perl code.


  • perldoc perlmod
  • perldoc lib
  • Perl Module Mechanics – a great guide containing practical HOW-TOs
  • How do I ‘use’ a Perl module in a directory not in @INC?
  • Programming Perl – chapter 31 part 13, ch 7.2.41
  • How does a Perl program know where to find the file containing Perl module it uses?

There does not seem to be a comprehensive @INC FAQ-type post on Stack Overflow, so this question is intended as one.

When to use each approach?

  • If the modules in a directory need to be used by many/all scripts on your site, especially run by multiple users, that directory should be included in the default @INC compiled into the Perl binary.

  • If the modules in the directory will be used exclusively by a specific user for all the scripts that user runs (or if recompiling Perl is not an option for changing the default @INC in the previous use case), set the users’ PERL5LIB, usually during user login.

Note: Please be aware of the usual Unix environment variable pitfalls – e.g. in certain cases running the scripts as a particular user does not guarantee running them with that user’s environment set up, e.g. via su.

  • If the modules in the directory need to be used only in specific circumstances (e.g. when the script(s) is executed in development/debug mode, you can either set PERL5LIB manually, or pass the -I option to perl.

  • If the modules need to be used only for specific scripts, by all users using them, use use lib/no lib pragmas in the program itself. It also should be used when the directory to be searched needs to be dynamically determined during runtime – e.g. from the script’s command line parameters or script’s path (see the FindBin module for a very nice use case).

  • If the directories in @INC need to be manipulated according to some complicated logic, either impossible or too unwieldy to implement by a combination of use lib/no lib pragmas, then use direct @INC manipulation inside a BEGIN {} block or inside a special purpose library designated for @INC manipulation, which must be used by your script(s) before any other modules are used.

An example of this is automatically switching between libraries in prod/uat/dev directories, with waterfall library pickup in prod if it’s missing from dev and/or UAT (the last condition makes the standard “use lib + FindBin” solution fairly complicated.
A detailed illustration of this scenario is in How do I use beta Perl modules from beta Perl scripts?.

  • An additional use case for directly manipulating @INC is to be able to add subroutine references or object references (yes, Virginia, @INC can contain custom Perl code and not just directory names, as explained in When is a subroutine reference in @INC called?).

Leave a Comment