NAME

perl-codemap - Create interactive Perl dependency graphs and source-code maps

SYNOPSIS

perl-codemap --root ./lib --output code-map.html
perl-codemap --root . --parser ppi --include-tests \
  --output architecture.html --json architecture.json
perl-codemap --from-json architecture.json --output updated.html
perl-codemap --from-json architecture.json --root ./original-source \
  --output updated.html
perl-codemap --help
perl-codemap --man
perl-codemap --version

DESCRIPTION

perl-codemap statically scans Perl source trees and produces a standalone, interactive HTML report with local package dependency diagrams, searchable subroutines and files, and an optional syntax-highlighted source browser. The program does not load or execute the source files it scans. It also supports machine-readable JSON exports and regenerating HTML from an existing JSON export.

The generated HTML contains its own CSS, JavaScript, and Perl syntax highlighter; it can be opened offline without a web server. Its source browser is available only when source was embedded in the report.

By default, the parser selects PPI when installed. Without PPI, it uses an intentionally limited heuristic parser (lite). For complex applications, install PPI and specify --parser ppi to require structural parsing.

INSTALLATION

Install the published CPAN distribution, then the recommended PPI parser:

cpanm Perl::CodeMap
cpanm PPI

perl-codemap is the command supplied by the Perl::CodeMap distribution. It requires Perl 5.20 or newer. PPI is recommended, not a hard dependency.

QUICK START

Analyze a directory containing Perl modules:

perl-codemap --root ./lib --output map.html

Open map.html in a browser. Select namespace groups and packages to explore local dependencies. Search for package names, files, methods, or subroutines; open a result to browse syntax-highlighted code when the report includes it.

Use --parser ppi to require PPI and --json map.json to export a reusable JSON representation.

OPTIONS

--root DIR

Root directory to scan, defaulting to the current working directory. Only recognized Perl source files beneath the root are considered. When used with --from-json, identifies the original source directory used to rehydrate source files. Without an explicit root in that mode, the program tries the original directory recorded in the JSON export if it still exists.

-o FILE, --output FILE

HTML report destination. Defaults to perl-code-map.html. The parent directory must exist and be writable; existing files at the destination are overwritten.

--json FILE

Also write the analysis data as JSON. This JSON may include complete source files (see --no-embed-source). Existing destination files are overwritten.

--from-json FILE

Load a previously generated CodeMap JSON export, then write a new HTML report. Requires a JSON object with a pkgs array. Use --root to attach source files from their original location if they were not embedded in the export. --parser is not used to reanalyze an imported JSON export.

--parser auto|ppi|lite

Analysis strategy, defaulting to auto. auto selects PPI if installed, otherwise the limited lite parser. ppi requires PPI and exits with an error if unavailable. lite forces the heuristic parser, which may miss or misinterpret complex Perl syntax.

--embed-source, --no-embed-source

Embed source contents in generated HTML and JSON (enabled by default). --no-embed-source excludes embedded source even when importing an existing JSON export. Excluding source disables the offline source viewer but retains package, file, and function metadata.

--max-source-bytes N

Maximum number of bytes to embed from any individual source file, defaulting to 2000000. Files above this limit still contribute metadata but not source text. Must be a positive integer.

--include-tests, --no-include-tests

Include or exclude .t files and common test directories (t/, xt/, test/, tests/). Excluded by default. Vendor and common build directories are skipped regardless of this option.

--source-base URL

Base URL for links from report files to a hosted GitHub/GitLab source tree. Use a URL that points to the root of the scanned source directory at a particular revision, normally ending in /. Relative source paths are appended to this URL; line-number anchors are added by the viewer. If omitted, the program attempts to detect GitHub's origin remote and current commit for a scanned Git checkout. Non-GitHub hosts normally require this option.

--name TITLE

Title displayed in the generated report. Defaults to the scanned directory's base name.

--version

Print the program version and exit.

-h, --help

Show command synopsis and option descriptions from this manual, then exit.

--man

Show this complete reference manual, then exit.

EXAMPLES

Map a Perl application

perl-codemap --root ./lib --parser ppi \
  --name 'My Application' --output architecture.html

Analyze a repository including its tests

perl-codemap --root . --include-tests --parser ppi \
  --output full-map.html --json full-map.json

Produce a metadata-only report

perl-codemap --root ./lib --no-embed-source \
  --output architecture-only.html

This avoids embedding full source text, but the HTML report may still include internal names and paths. Treat outputs from private repositories as private.

Re-render an existing analysis without rescanning

perl-codemap --from-json previous.json --output latest.html

Reattach code to an old export

perl-codemap --from-json previous.json \
  --root /path/to/original/source-root \
  --output with-source.html

The root must match the source directory relative to which the paths in the original JSON were recorded. Rehydration rejects paths that escape that root.

perl-codemap --root ./lib --parser ppi \
  --source-base 'https://gitlab.example.org/team/app/-/blob/COMMIT/lib/' \
  --output code-map.html

Replace COMMIT with an immutable revision and update the host, project, and subdirectory to match your actual repository.

INPUT FILES AND OUTPUT

The scan considers .pm, .pl, .psgi, optional .t files, and extensionless files whose shebang declares Perl. Hidden directories, symlinks, common vendor paths, and generated build directories are not traversed. Discovered dependencies are limited to statically recognizable packages present inside the scanned source root; external installed modules do not appear as dependency nodes unless their source is also included in that root.

The HTML report is self-contained and requires JavaScript in the browser. A JSON export contains the same metadata and, unless disabled, an additional sources object with potentially complete source files.

EXIT STATUS

0

Command completed successfully, or --help, --man, or --version was requested.

1

No Perl packages were found beneath the selected root.

2

Invalid option, configuration, missing PPI when explicitly required, invalid JSON input, or a report read/write error.

LIMITATIONS

This is a static architectural visualization, not a runtime call graph. Dynamic require, dynamic method dispatch, AUTOLOAD, generated code, Moose modifiers, Catalyst routing, and DBIx::Class runtime relationships are not fully modeled. Multiple package declarations per file are supported, but block-scoped constructs are best effort.

SECURITY AND PRIVACY

Reports embed source code by default. Do not place generated HTML or JSON from a private application on public GitHub Pages, issue trackers, or CI artifacts. Such reports can reveal secrets, internal paths, and proprietary code. --no-embed-source reduces exposure but does not remove sensitive package or function names.

Source is statically parsed, not evaluated. The tool is not a secrets scanner or a security sandbox.

SEE ALSO

Perl::CodeMap, PPI, Pod::Usage, Perl CodeMap on MetaCPAN, Live sample, Source and issues.

AUTHOR

Scott Muller <scott@21h.io>

COPYRIGHT AND LICENSE

Copyright (c) 2026 Scott Muller. Released under the MIT License. See the project's LICENSE and NOTICE.md for acknowledgments and third-party licenses.