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

Versaorm Php Laravel Package

versaorm/versaorm-php

VersaORM is a lightweight, expressive PHP ORM featuring a fluent query builder, active-record models, relationships, and schema migrations. It supports popular databases and keeps your data layer clean without heavy dependencies or complex configuration.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. VersaORM is a standalone PDO-backed ORM with its own fluent builder, its own connection handle, and its own Active Record base class. It ships no service provider, no facade, no DB manager driver, and no Eloquent bridge — so it does not slot into the framework's data layer, it sits beside it. That is the central architectural fact and it should drive the product decision: this is a second data layer for a narrow workload, not a replacement for Eloquent and not a general-purpose persistence strategy. A realistic fit is one of two shapes: (a) pgvector similarity search on PostgreSQL 16, or (b) hand-tuned analytical/reporting reads where DB::select with a heredoc would otherwise be the alternative. Anything involving domain CRUD, relationships, events, or transactions stays in Eloquent, which means two PDO connections per request in the common case.

Integration feasibility. Low-to-moderate effort, high ambiguity. There is no first-party Laravel integration, so wiring is a manual singleton in AppServiceProvider plus a config/versaorm.php sourced from the same env vars as config/database.php. The only complete end-to-end sample is example/app/ — and its BaseModel was broken until 2.0.1 because it overrode the now-final find(). Two items must be resolved in the first hour of any spike: (1) the Composer package name is genuinely ambiguous (versaorm/versaorm-php in the listing vs. kriollo/versa-orm in the repo) — confirm against Packagist before planning install steps; (2) pin 2.0.1 literally, not ^2.0, because 2.0.0 shipped a correctness bug.

Technical risk. The dominant risk is not breakage — it is silent wrong answers. In 2.0.0, selectRaw()/orderByRaw() dropped their bindings; PostgreSQL threw, but SQLite and MySQL returned NULL in a result column with no exception. That is the failure mode to plan around, and it is a data-integrity risk, not an availability risk, which makes it materially more expensive. Compounding factors:

  • Supply chain: 5 stars, 0 dependents, single maintainer, no commercial backing. Effective support is "the maintainer's free time." There is no ecosystem to lean on for answers.
  • Validation gaps: the headline pgvector feature had all 13 tests skipped locally and in CI until 2.0.1 — it shipped unverified. The strong signals (PHPStan level 9 clean, php-cs-fixer clean, ~3,200 tests across three engines) are real but did not catch it.
  • Security-adjacent heuristic: # is treated as a MySQL comment start unless preceded by <. That filter was tightened in 2.0.1 to unblock pgvector's <#> operator, and it must be re-reviewed on every upgrade.
  • Missing ecosystem features: no pagination/paginator, no model events, no factories, no SoftDeletes, no casts, no mutators, no withCount, no find() override (final since 1.8.8). Each is a scoped decision, not a surprise to discover mid-sprint.
  • Environment coupling: PostgreSQL 15+ removed the implicit write grant on public; the DB-level GRANT is insufficient and every CI job dies without GRANT ALL ON SCHEMA public.

Key questions to answer before committing roadmap or headcount:

  1. Which specific workload justifies a second connection pool, and what is its measured pain today under Eloquent/DB::select?
  2. Who owns upgrade gating? If nobody owns reading each changelog as a potential correctness note, this dependency will drift into a silent-corruption incident.
  3. Is any correctness-sensitive number (revenue, price, score, ranking) computed through this package? If yes on 2.0.0 anywhere, that is a data audit, not an upgrade.
  4. What is the exit cost if the maintainer stops shipping? Repository wrappers make it a days-not-weeks swap — is that acceptable, and is it written down?
  5. Does the pgvector ceiling (comfortable into the low millions of vectors with a proper HNSW index) clear our 18-month volume and latency SLO? Past that, "no separate vector DB" stops being an advantage.
  6. Is there budget for the hand-rolled gaps (pagination, paginator construction, connection lifecycle under Octane) across every endpoint that uses it?

Integration Approach

Stack fit. Adopt only where Laravel is genuinely awkward: vector similarity retrieval, cohort/funnel arithmetic, weekly revenue rollups, CSV/report exports for admin screens. Keep Eloquent for CRUD, relationships, policies, factories, casts, Nova, and all writes and transactions — if a vector insert and a domain write must be atomic, they must share one connection, and straddling two stacks inside a transaction produces partial commits that are hard to explain after the fact. Resolve the ORM lazily inside the controllers, jobs, and commands that need it; keep it out of hot CRUD paths.

Migration path. Do not start by porting a domain model. Start with a read-only spike against a restored copy of production, and gate it on three environment facts confirmed up front: PostgreSQL major version, vector extension installed, and GRANT ALL ON SCHEMA public applied. Use 127.0.0.1, not localhost — PdoConnection has defaulted to TCP since 1.9.0 and localhost can resolve to a Unix socket and fail with a confusing error. Prove one query end-to-end (similarity search or an aggregate), then wrap it in a repository.

Compatibility. Assume zero framework features and plan each one explicitly. Concretely: hand-roll LengthAwarePaginator construction from a count plus limit/offset fetch on every listing view; write schema changes (vector columns, HNSW/IVFFlat indexes, grants) as Laravel migrations, since VersaORM is not a schema tool; confine env() to config files, doubly so here because the package reads a plain array you build and config:cache will silently return null elsewhere. Respect the hard binding-order rule (SELECT → WHERE → GROUP BY → HAVING → ORDER BY) — if a value appears in both SELECT and ORDER BY, supply it twice. And note that select() replaces the column list wholesale, so calling it after selectVectorSimilarity() erases the similarity expression.

Sequencing.

  1. Week 1 — resolve ambiguity and spike. Confirm the Packagist name, pin 2.0.1, wire the singleton, read example/app/config.php, example/app/BaseModel.php (do not copy the find() override), tests/unit/Regression/ (19 tests, 14 of which fail against 1.9.0 — the closest thing to a behavioural spec), and the 2.0.1 changelog end to end.
  2. Week 1–2 — read-only proof. One vector query or one aggregate against production-like data, behind a repository in app/Queries/ or app/Repositories/. Assert non-null on every computed column.
  3. Week 2–3 — instrumentation. Local-only logger dumping SQL and bindings before execution; CI jobs on SQLite (speed), MySQL, and PostgreSQL — with staging on the production engine, because the 2.0.0 bug threw loudly on PostgreSQL and returned silent NULLs elsewhere, which is exactly the asymmetry that makes "passed in staging" untrustworthy.
  4. Week 3+ — expand by workload, not by surface area. Analytics on a replica registered as a named singleton (versaorm.readonly), since the package has no read/write splitting; an Artisan reindex command; a queued backfill job resolved from the container.
  5. Never — treat it as a replacement for Eloquent, or put it inside a transaction boundary shared with domain writes.

Operational Impact

Maintenance. Ongoing cost is meaningfully above a typical Composer dependency: you own the upgrade gate, the security review of the # comment heuristic, the changelog-as-correctness-notes discipline, and every gap the framework normally fills. Budget a recurring line item — roughly a day per upgrade cycle plus test-suite revalidation — and name an owner. If no one owns it, it will be upgraded opportunistically during a dependency sweep and that is precisely how a silent-corruption regression reaches production.

Support. Effectively none, in the commercial sense. Zero dependents means no community corpus: no Stack Overflow answers, no blog posts, no third-party packages. Internal knowledge is whatever the spike team writes down. Mitigate by keeping every ->table() chain inside app/Queries//app/Repositories/ so the abstraction boundary is a real exit ramp, and by documenting the pin rationale so the next engineer does not "helpfully" bump to ^2.0.

Scaling. Two dimensions. Throughput: two PDO connections per request is additive but not free; keep the singleton out of hot paths and resolve lazily. Under Octane or long-lived workers, a singleton holding a PDO handle survives across requests — usually fine, but if stale-connection or "server has gone away" errors appear, bind scoped/transient rather than singleton. Data volume: pgvector with a proper HNSW index is comfortable into the low millions of vectors; past that, revisit the "no separate vector database" premise before the roadmap depends on it.

Failure modes, ranked by expected cost:

  • Silent incorrect results (highest). Wrong bindings → NULL in a computed column, no exception, on SQLite/MySQL. Countermeasures: pre-execution SQL+binding logging in local/test, non-null assertions on every computed column, and engine parity in CI. Any production exposure on 2.0.0 is a data audit against a source of truth, not a version bump.
  • Connection/provisioning failures. localhost-as-socket resolution, missing GRANT ALL ON SCHEMA public on PG 15+, cached config returning null for a stray env(). All preventable in setup scripts.
  • Comment-filter regression. A future #-handling change could re-break <#> or, worse, weaken injection defenses. Re-check every upgrade.
  • Abandonment. Repository wrappers make this a days-to-weeks swap rather than a rewrite — the primary mitigation, and worth stating as an explicit architectural decision.
  • Transaction straddling. Partial commits across two connections; preventable by policy, not by tooling.
  • Ecosystem gaps surfacing mid-sprint. Pagination and paginator construction are the predictable ones; scope them per endpoint up front.

Ramp-up. A mid-level Laravel developer becomes productive in roughly half a day if they read the regression suite and the 2.0.1 changelog first, and roughly a week of avoidable thrash if they don't — the package's own maintainers lost three tests to $orm->getAll() (which does not exist; row retrieval lives on the builder chain) and to calling select() after selectVectorSimilarity(). Frame onboarding explicitly as "a specialised query library for one workload," not "a lighter Eloquent," because the second framing invites a model port that will hit the final find(), the missing casts/timestamps, and the absent pagination all in the same sprint.

Bottom line. Viable as a bounded, read-only, non-correctness-critical accelerator for pgvector or analytical reads, contingent on a two-week spike, a named upgrade owner, and repository wrapping. Not viable as a data-layer replacement, not viable where a numeric result must be right without an independent assertion, and not viable without accepting single-maintainer supply-chain risk.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log