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

Uxdm Laravel Package

jord-jd/uxdm

UXDM is a PHP data migration library for moving records between sources and destinations such as CSV, JSON, XML, PDO and Eloquent. Map fields, transform values, and run repeatable imports or exports through a simple, extensible API.

Deep Wiki
Context7

Technical Evaluation

Architecture fit

UXDM is a framework-agnostic PHP data-migration library, not a Laravel package. Its model is a linear pipeline: one or more sources (array, PDO/database, CSV-style file sources) feed migrators (item-level field mapping, field transformers, relation handling) and emit to one or more destinations (array, database, file). That is a reasonable fit for the class of work Laravel teams routinely hand-roll: seeding a new schema from a legacy CRM/ERP export, backfilling a normalized table from a denormalized one, or re-platforming between two apps.

Importantly, it is a build-time/tooling dependency, not a runtime dependency. Nothing in the product request path touches UXDM; it runs as a batch job, an Artisan command, or a queued worker. That materially lowers the blast radius of adopting a low-adoption package, and it means the architecture decision is really "do we adopt this as our ETL scaffold, or write ~300–600 lines of bespoke chunked-mapping code?"

Where it fits poorly: anything event-driven, CDC/incremental-sync, or requiring strong transactional guarantees across heterogeneous systems. UXDM is oriented at batch, run-to-completion migrations. If our roadmap needs ongoing two-way sync, this is the wrong tool and we should say so early.

Integration feasibility

Composer-installable, no service provider, no facade, no published config — so integration is deliberately manual. In a Laravel codebase that means we own the wiring: an artisan command per migration, a config/migrations/*.php style registry, logging via our existing channels, and wrapping each run in a job so long migrations do not block deploys. That is a day or two of scaffolding, not a week.

The fluent, chainable API is the main draw: field mapping reads close to declarative config, which is reviewable by non-authors and diffable in PRs. That is a genuine advantage over a bespoke foreach loop for auditability during a cutover.

The friction points are Laravel-native ergonomics we do not get for free: no queue/event hooks, no built-in progress reporting, no chunk/resume semantics we can rely on without verifying, and no first-class Eloquent support (it works at the PDO layer).

Technical risk

  • Supply chain (high). Repository metadata is unavailable in the registry entry we have, so we cannot verify CI status, issue responsiveness, security-advisory process, or commit cadence. 164 stars implies a small user base and thin community testing.
  • Bus factor (high). Effectively a single-maintainer project. We must assume we may need to fork.
  • License (medium, but blocking until cleared). LGPL-3.0 is unusual for PHP libraries and its "linking" boundary is genuinely ambiguous for interpreted languages. Internal-only use is low risk; redistribution or SaaS delivery needs a written opinion from counsel before we commit. If we fork and distribute, our modifications carry LGPL obligations.
  • Correctness risk (medium). Data migrations fail silently — off-by-one field mappings, timezone drift, null-vs-empty-string coercion, truncation. The library cannot protect us from that; our reconciliation tests must.
  • Performance risk (medium). Object-per-row pipelines have memory ceilings. We do not know from the metadata whether chunking/streaming is first-class. Must be proven on representative volume, not assumed.

Key questions

  1. What is the canonical upstream repository, and what does its CI, release cadence, and issue backlog look like over the last 18 months?
  2. Does the PHP version constraint cover our target (8.2/8.3) and does it support all PDO drivers we use?
  3. Is there streaming/chunked iteration, or does the pipeline materialize the full dataset in memory? What is peak RSS at 1M rows?
  4. What are the retry/idempotency semantics — can a failed run be safely re-executed, or do we get duplicates?
  5. Does it expose transaction boundaries, per-row error hooks, and progress callbacks we can wire to our observability?
  6. Will Legal sign off on LGPL-3.0 for our distribution model (internal tool vs. shipped product)?
  7. How does it handle relations/foreign-key ordering — does it sequence parent-before-child, or is that our responsibility?

Integration Approach

Stack fit

Good fit as a migration workbench inside the Laravel monolith, invoked from Artisan commands and queued jobs. It complements rather than competes with Laravel's schema migrations: Laravel owns DDL, UXDM owns DML for cross-system loads. We should avoid introducing it into request-path code or into packages we publish.

Migration path

Adopt behind an anti-corruption layer. Define our own thin interfaces — SourceReader, RecordMapper, DestinationWriter — and implement them with UXDM internally. Cost: roughly 2–3 days. Benefit: if the package stalls, the swap to a bespoke chunked writer is a contained change rather than a rewrite, and unit tests can target our interfaces with fixtures instead of the vendor's objects.

Compatibility

Framework-agnosticism is a double-edged property: we are insulated from Laravel major-version churn, but we also inherit zero Laravel integration. Concrete compatibility checks before commitment: PHP constraint vs. our runtime, PDO driver coverage (MySQL/Postgres/SQLite), behavior under declare(strict_types=1) and our static-analysis baseline (PHPStan/Larastan level), and whether it plays nicely with our test suite's database transactions.

Sequencing

  1. Week 0 — due diligence. Locate the repo, review license with counsel, run a dependency/security scan. Gate: go/no-go.
  2. Week 1 — spike. 2–3 days: load a 100k-row anonymized slice from the source system into a scratch schema; measure throughput, peak memory, and failure behavior on malformed rows.
  3. Week 1–2 — adapter + fixtures. Build the wrapper layer and a golden-file test harness. Establish reconciliation queries (row counts, checksums, sampled field diffs) as reusable artifacts.
  4. Week 2–3 — dry runs. Full-volume rehearsal against a production snapshot in staging, repeated at least twice to prove idempotency. Produce a runbook.
  5. Week 3–4 — pilot entity. Migrate the lowest-risk, lowest-fan-out entity first. Hold.
  6. Cutover. Remaining entities in dependency order, with a documented rollback (restore-from-snapshot plus replay) and a freeze window.
  7. Post-migration. Archive scripts, tag a branch, write the one-page "how to run this again" doc, and record the fork decision.

Operational Impact

Maintenance

Treat this as a vendored dependency with an internal owner, not a community package. Pin the exact version in composer.json, commit composer.lock, and mirror the source in our VCS so an upstream deletion cannot break a rebuild. Budget roughly 1–2 engineer-days per quarter for upgrade triage; more if we fork.

Support

There is no vendor and no SLA. Escalation is "the named DRI on our team reads the source." That DRI must exist before adoption — if we cannot name them, we should not take the dependency. Community support at 164 stars means issue turnaround should be assumed to be weeks or never.

Scaling

Assume batch throughput is bounded by destination write performance, not by the library. Levers we control: disable non-clustered indexes and FK checks during load and rebuild after, batch sizes tuned to memory, parallelize by disjoint entity sets, and run against a read replica for the source. If per-record object overhead proves to be the ceiling above ~500k rows, the fallback is a bespoke PDO::FETCH_ASSOC streaming loop — which is precisely why the adapter layer matters.

Failure modes

Ranked by likelihood × impact:

  • Partial writes on crash (high/high) — half-migrated tables with no way to tell where it stopped. Mitigate with per-batch checkpointing and idempotent upserts.
  • Silent field-mapping drift (high/high) — source schema changes, mapping keeps "working," data is wrong. Mitigate with schema assertions and reconciliation checksums on every run.
  • Duplicate records on retry (medium/high) — mitigate with natural-key uniqueness constraints and INSERT ... ON DUPLICATE KEY UPDATE semantics.
  • Memory exhaustion mid-run (medium/medium) — mitigate with chunked invocation.
  • Lock contention / long transactions on destination (medium/medium) — mitigate by running in a maintenance window.
  • Encoding, timezone, and date-format corruption (medium/medium) — mitigate with explicit transformers and spot-check assertions.

Every one of these is a job failure, not a user-facing outage — which is the core argument for the risk being acceptable.

Ramp-up

The library itself is a half-day to learn; the fluent API is small and self-documenting. Realistic ramp-up for a mid-level Laravel engineer to productive-and-safe is 3–5 days, of which the majority is spent on domain mapping, reconciliation strategy, and the runbook — not on UXDM. That is the right way to frame the cost/benefit: we are buying roughly 1–2 weeks of ETL scaffolding, and paying for it with a supply-chain risk that must be capped by the adapter layer and the fork-ready posture.

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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource