Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Cartographer Laravel Package

byrcsc/laravel-cartographer

Laravel Cartographer helps you map and visualize your Laravel application's structure. It gives a clear overview of routes, controllers, models, and their connections, making large codebases easier to navigate, debug, and refactor. Ideal for onboarding and understanding unfamiliar projects.

View on GitHub
Deep Wiki
Context7

Getting Started

laravel-cartographer turns your Eloquent models into Mermaid ER diagrams that live in the repo next to the code. v1.2.0 is still a small package — the whole day-to-day surface is config plus two commands — so you can be productive in about ten minutes.

  1. Install as a dev dependency. It only reads model metadata and writes docs, so it does not belong in production:

    composer require --dev byrcsc/laravel-cartographer
    php artisan vendor:publish --tag=cartographer-config   # config/cartographer.php
    

    Check your platform first: PHP 8.3+, Laravel 12 or 13, plus symfony/process ^7.2 || ^8.0. Composer will silently keep you on an older tag (or fail resolution) if you are on PHP 8.2 or Laravel 11 — that is deliberate, but it is the first thing to verify on CI images and older containers.

  2. Read the config file before the docs. The release only mentions two keys by name — groups and themes — but everything you care about (model paths, output file, exclusions) is declared there. The published config is the real reference; https://docs.rcsc.dev/laravel-cartographer/v1/introduction fills in the semantics.

  3. Generate once and commit the result.

    php artisan cartographer:generate   # writes docs/erd.md
    git add docs/erd.md && git commit -m "docs: initial ERD"
    
  4. First real use case: wire the drift check into CI immediately. The value of a committed diagram is only realised when it cannot silently rot.

    # .github/workflows/docs.yml
    - run: php artisan cartographer:check
    

    It regenerates in memory, writes nothing, and exits 1 with a per-file diff when something is stale — safe on a read-only checkout with no build artefacts.

If you only do one of the v1.2.0 features on day one, make it cartographer:check.

Implementation Patterns

Named groups for per-domain diagrams

One diagram of a 90-model app is unreadable and useless for review. Groups give each team the slice they talk about, committed as a sibling file: the main docs/erd.md produces docs/erd/billing.md, docs/erd/catalog.md, and so on.

// config/cartographer.php — illustrative shape, confirm key names against the published config
'groups' => [
    'billing' => ['App\Models\Invoice', 'App\Models\Payment', 'App\Models\Subscription'],
    'catalog' => ['App\Models\Product', 'App\Models\Category'],
],

php artisan cartographer:generate --group=billing regenerates just one file, which is the loop you want while refactoring a domain: iterate, eyeball the diff on docs/erd/billing.md, commit. Full runs regenerate all groups plus the main diagram.

Adopt groups when a single diagram passes roughly 20–30 models, or when two teams stop reading the same file.

Drift checks as a PR gate

cartographer:check is the centrepiece of this release. The useful pattern is not "check the diagram" but "check the diagram in the same job that checks code style", so a schema change and its diagram land in one commit:

- run: composer install --no-interaction --prefer-dist
- run: php artisan cartographer:check   # exits 1 and prints the stale files + short diff

Because it lists each stale file rather than failing anonymously, the output is usually enough to tell a developer "you added a column and forgot composer erd" without opening the log twice.

Scoping a run without touching committed files

--only and --except are for one-off exploration, not for committing narrower output. They deliberately leave the committed group files alone, so a run with --only=App\Models\Invoice will not rewrite docs/erd/billing.md:

# Quick look at a subtree while debugging a relation
php artisan cartographer:generate --only=App\Models\Order --format=svg

# Everything except a noisy legacy namespace
php artisan cartographer:generate --except=App\Models\Legacy

Good for local use, for a throwaway diagram in a PR description, or for a spike. Not a substitute for a group.

Image export for humans, Markdown for machines

--format=svg|png renders through mermaid-cli, which you install yourself (node + @mermaid-js/mermaid-cli); it is intentionally not a package dependency. The important detail is that the Mermaid source is written beside the image, and that source — not the PNG — is what cartographer:check compares. So:

  • Committing SVGs/PNGs gives reviewers and Confluence/Notion readers something to look at.
  • CI can verify those exports without installing node, because only the .mmd/source file is diffed.
npm install -g @mermaid-js/mermaid-cli
php artisan cartographer:generate --format=svg --theme=dracula --font=mono

Keep image generation out of the default composer erd script unless everyone on the team has node; make it an opt-in --format flag so a plain run stays fast and dependency-free.

Themes and fonts stay out of the repo

--theme=light|dracula (or a preset you define under themes) and --font=mono|sans|default apply to images only. Committed Markdown is deliberately theme-neutral, so there is no churn in .md diffs when someone changes presentation. Treat theming as a local/export concern and put your team's house style in themes in config so nobody retypes flags.

Programmatic generation

DiagramGenerator is now a public entry point and every command runs through it — which means anything a command can do (export, theming, limits) is available to you. Reasonable uses: a custom Artisan command that posts a diagram to a PR, a test asserting a group is non-empty, or a post-migration hook in local dev. Prefer calling the generator over shelling out to the artisan commands; you get the return values and exceptions instead of parsing console output.

Per-model relationship caching

Relationship detection is cached per model within a run, so drawing a model into the full diagram and into three of its groups costs one detection pass. If you are on v1.0.0 and running a full generation with several groups, this alone noticeably shortens the run. No configuration required.

Gotchas and Tips

  • The 50,000-character / 500-edge warning is advisory only. It fires on the run that crossed the limit, never trims the diagram, and never changes the exit code. That means cartographer:check can be green while your committed diagram is guaranteed to fail on GitHub's or Mermaid Live's hosted renderer. If you publish diagrams anywhere hosted, treat that warning as an error in your own CI (... | tee and grep for it), or keep the main diagram small and push detail into groups.
  • A passing check does not mean your images are current. It compares the Mermaid source. If you commit docs/erd.svg and the source drifts, the check still passes and the image is stale. Either regenerate images in the same step as the source, or treat images as build artefacts.
  • check regenerates everything the config declares. Adding a group is a breaking change for CI in the good sense: the first run after adding a group fails until you commit the new file. Expect that on the PR that introduces the group, and commit the generated file in that same PR. The same applies after any intentional model change — the fix is to run cartographer:generate locally.
  • --only/--except can hide drift. They don't touch committed group files, so a scoped run can leave a group stale while the developer believes they just regenerated. Always finish with a full cartographer:generate (or a check) before pushing.
  • Cross-group relations become empty boxes. A relation leaving a group keeps its edge, with the far model drawn as an unnamed empty node. That is intentional and keeps groups readable — but it means the reader needs the neighbouring diagram for context. Note it in the group's intro line in the README so nobody files a bug.
  • mermaid-cli failures are environment failures, not diagram errors. Rendering needs a headless Chromium; container images without the right libs (or a puppeteer sandbox config) fail at export while the Markdown generation is perfectly fine. Isolate image export into its own CI job or local script so a broken node setup never blocks the drift check.
  • Composer silently holding you back is the most common "the feature doesn't exist" report. --group, cartographer:check and --format are v1.2.0+; if php artisan list shows no cartographer:check, run composer why-not byrcsc/laravel-cartographer and look at PHP/Laravel/symfony versions before reading the docs again.
  • Themes do not apply to Markdown, so don't try to fix "ugly GitHub rendering" via --theme. GitHub uses its own Mermaid theme; --theme/--font only affect exported images.
  • Where to extend: themes in config for house styles; DiagramGenerator for anything scripted; the published config for paths/exclusions. There is no event or macro surface described in this release, so don't plan around one.
  • Treat docs/ as generated-but-reviewed. Reviewing the diagram diff is the whole point — it is a cheap way to catch an accidental belongsTo or a missing foreign key in code review. Don't add it to .gitattributes as binary or otherwise hide the diff.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource