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

Migrator Laravel Package

statamic/migrator

Statamic Migrator brings Laravel-style migrations to content, letting you define repeatable migration classes that import and transform external data into Statamic collections and taxonomies, run via Artisan.

View on GitHub
Deep Wiki
Context7

Getting Started

Resolve what you're holding before you install. Two readings of this package circulate and they lead to completely different adoption plans: (a) Laravel-style migration files for Statamic content structure — collections, blueprints, fieldsets, taxonomies, run via Artisan, tracked and rollback-able; or (b) a one-shot legacy-major content importer for Statamic v2 → v3. The published description reads as (b); the package name reads as (a). The source is small enough to settle this in an afternoon. Until you do, treat every command name below as "confirm against src/."

Install into an isolated context, not production. This is a bridge, not infrastructure. Put it on a migration branch, in require-dev, pinned to an exact version.

git checkout -b migration/v2-to-v3
composer require statamic/migrator --dev
php please list | grep -i migrat
php artisan list | grep -i migrat

Statamic registers addon commands under php please; Laravel's native migrator commands live under php artisan. Which surface the package hooks into tells you immediately which product it is.

Where to look first, in order:

  1. src/ServiceProvider.php — what commands, config, and bindings are registered. This is the whole product surface at 43 stars.
  2. src/Console/ — the actual import steps. Read the command signatures before running anything.
  3. config/ — publish it and read every key. Source paths and migration options gate what gets imported.
  4. composer.json — the Statamic / Laravel / PHP matrix. Check it against your real v2 source and v3 target before scoping the work.
  5. tests/ — the maintainers' own assertions are the only documentation you'll get.

First use case — a representative pilot, not the full site. Stand up a throwaway v3 install alongside a clone of the v2 site. Point the migrator at one collection and a handful of entries. Run it. Then verify against these three gates, in order:

  1. Counts — do entry, term, and asset counts match the source?
  2. Raw YAML — git diff in content/ and resources/blueprints/ reads as you predicted, field by field.
  3. Rendered pages — the imported entries actually boot and render in the new install.

The success condition is not "the command exited zero." It is that the diff is legible and the site boots.

Implementation Patterns

Pilot → full → delta, each with a written go/no-go. The description's "repeatable" claim is the whole value proposition, and it only pays off if you structure the work iteratively. Run a representative subset first (one collection, a handful of entries, a sample of assets), verify counts, relationships, and rendered pages, then run the full volume, then run again for the delta between the last run and the content freeze. A single high-variance big-bang import is not a plan you can get approved.

Order the runs by dependency, not by whatever the command list emits. Users, roles, and site settings before anything that references them. Assets before entries that embed them. Taxonomies before terms. Collections before entries. If the package lets you control ordering, use it; if not, drive the commands yourself one at a time rather than invoking a single "migrate everything" wrapper.

Split structural runs from content runs. Structure (collections, blueprints, fieldsets, taxonomies) is cheap and you will want to re-run it. Content (entries, terms, users, assets) is expensive and you want it re-runnable as a delta. Keeping the two gates separate means you can iterate on the cheap part without touching the expensive part — and you can snapshot and restore content independently.

Keep git diff as your primary test harness. The most valuable workflow here is procedural: snapshot → run one step → git diff --stat content/ resources/ users/ → eyeball the YAML → git reset --hard if wrong → adjust → repeat. Flat-file CMSes make this trivially powerful and it catches field mismapping that no assertion will, because there is no schema to assert against.

Snapshot before every non-trivial run. Version content/, users/, resources/blueprints/, resources/fieldsets/, and any asset directories. down() on a content import is not a true inverse — deletes, overwrites of existing entries, and asset moves are typically not recoverable. Restore-from-snapshot is your real rollback path, so make it cheap.

Cache discipline between steps. After any import step, run php please stache:clear (and stache:warm if you're validating render output) before concluding anything. Half the "the migration didn't take" reports are a stale Stache index, and you will burn hours on them otherwise.

Wire the pilot into a disposable environment. Fresh clone → composer install → run the import steps → the v3 install boots with a matching content model. If that stops being true, the migration procedure has rotted and you need to know before cutover, not during it.

Delta-run cadence against a content freeze. The plan that makes the cutover safe is: freeze editorial changes → run the delta import → verify → flip DNS → keep the snapshot window open. Design the freeze length around how long a single delta run plus verification actually takes on your content volume — measure it during the pilot, don't estimate it.

If it turns out to be the schema-as-code tool (verify against src/): one logical change per migration file, idempotency guard at the top of every up(), and name files so lexical sort matches dependency order. The same discipline as Laravel migrations, but harder because the target is YAML on disk rather than a transactional database — there's no schema table protecting you from a partial write.

Gotchas and Tips

Stache drift is the default failure mode. Structural changes write YAML to disk; Statamic's Stache is a separate index. Any time behavior looks wrong, clear the cache first. The inverse is also true — a clean render after stache:warm is real evidence, a clean render without it isn't.

Drafts, revisions, and localization are where it goes quiet. Drafts and revisions live alongside entry content in the flat-file tree and are the classic silent-loss surface. After any content run, explicitly check: do drafts still exist, do revisions still resolve, does each site/locale directory have its entries. Absence of errors is not evidence of presence — verify the file tree directly.

Custom fieldtypes pass through or get dropped and you won't be told which. Before scaling past the pilot, inspect the raw YAML for one entry using each custom fieldtype. If the fieldtype stores a reference (an ID, a path, a filename), verify the reference still resolves on the target — copying the string is not the same as preserving the relationship.

Version window is a hard gate. Confirm the exact Statamic / Laravel / PHP matrix from composer.json against your real v2 source and v3 target during the spike. If it targets a version pair you're not on, the honest options are fork, write a bespoke ETL script, or stop. Decide that in week one, not at cutover.

You are the QA. 43 stars and zero dependents means no Stack Overflow answers, no blog posts, no community to escalate to. First-party provenance is a real signal worth raising through any support agreement, but it is not an SLA. Pin the version, read the source, and budget for an internal fork — the package is small enough that forking is a realistic option rather than a threat.

CP drift, if this turns out to be the schema tool. Once migrations describe structure, someone will edit a blueprint in the Control Panel and the files will quietly stop describing reality. Pick a policy in writing — either migrations are the source of truth and CP structural edits are forbidden, or migrations are one-shot and deleted after adoption — and enforce it. Both being true is the failure that bites six months later.

Debugging toolkit: -vvv on every command; run one step at a time rather than the whole batch; git diff the emitted YAML rather than inspecting through the CP; and keep a clone of the pre-migration v2 site on disk to diff against. When something looks wrong and the cache is clear, the answer is in the raw YAML — read it directly.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core