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 Tags Laravel Package

rinvex/laravel-tags

Rinvex Laravel Tags adds flexible tagging to Eloquent models, letting you attach tags and tag types to any model polymorphically. Manage tags, slugs, and relationships easily with a clean API for building searchable, categorized content in Laravel apps.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

rinvex/laravel-tags implements the standard polymorphic tag pattern for Eloquent: a tags table, a taggables pivot (taggable_type, taggable_id, tag_id), and a HasTags trait mixed into any model. That is the correct shape for this problem and maps cleanly onto any Laravel domain model we already own. It also advertises slug generation and translation of tag names out of the box, which is table stakes for any product with multi-locale taxonomy.

The architectural concern is not the pattern, it is the dependency graph. The package builds on rinvex/laravel-support (and, for translations, likely spatie/laravel-translatable — verify in composer.json). That means adopting a 29-star archived package pulls in a second-order dependency from the same vendor as a hard requirement for our core content model. We would be inheriting an unmaintained transitive layer in the middle of our persistence code, which is the hardest place to refactor later.

Integration feasibility

Installation is low-effort and conventional: composer require, publish migrations and config, run migrations, add the trait plus a $taggable / taggable-type registration to each model. A competent Laravel engineer can have a working spike in under a day. There is no service provider complexity, no queue/worker surface, no external service, no runtime infrastructure. Integration cost is genuinely small — which is precisely why the decision should be made on ownership cost, not on effort.

The feasibility blocker is version compatibility. With the repo archived, there is no evidence of support for Laravel 10/11/12 or PHP 8.2+. Treat the declared constraints as stale until proven otherwise, and expect the trait and migration stubs to need patching against current framework conventions (attribute casting, anonymous migration classes, Model::preventLazyLoading, etc.).

Technical risk

  • Archived upstream (highest severity). No security patches, no framework-compat fixes, no bug triage. Any CVE in the dependency chain or any Laravel major upgrade becomes our work.
  • Zero dependents / 29 stars. No community validation, no Stack Overflow corpus, no third-party PRs to lean on. Effectively a single-author project that has stopped.
  • Vendor-pattern risk. The Rinvex package family has a history of mass archival and licensing changes across major versions. MIT applies to the pinned version we vendor, but we should confirm the license of the exact tag we install rather than the repo default.
  • Feature overlap. spatie/laravel-tags covers the same ground with active maintenance, first-party docs, and broad adoption. Choosing the archived option requires a positive reason, and the description offers none.
  • Data-model lock-in. Tag data is reference data that other features (search, recommendations, filtering, SEO) will read from. Migrating a polymorphic pivot after the fact means dual-writes and a backfill across every taggable table — a real, scheduled project rather than a refactor ticket.

Key questions

  1. What is the actual reason to prefer this over spatie/laravel-tags? If the answer is "translated tag names," confirm whether Spatie's translatable integration closes the gap.
  2. Which Laravel/PHP versions must we support at launch and 18 months out, and does the pinned version satisfy the first with margin?
  3. Are tag translations a launch requirement or a Phase 2 requirement? If Phase 2, a translated tag schema at launch is speculative complexity.
  4. Do we have a named internal owner willing to fork and maintain this? If not, the answer is no.
  5. What is the expected tag volume and read pattern (facet counts, tag clouds, filtered listings)? That, not the package, determines whether the pivot table needs denormalized counters or a search index.

Integration Approach

Stack fit

Fits a conventional Laravel monolith or modular monolith with MySQL/Postgres. No fit with event-sourced or read-model-heavy architectures without wrapping it, because the trait writes synchronously to the pivot on model save. If we already run a search layer (Meilisearch, Typesense, Algolia, Elasticsearch), tags should be projected there for faceting and the DB pivot treated as system of record only — the package has no opinion on this.

Migration path

  • Greenfield: acceptable as a spike, but the default should be Spatie. Adopt Rinvex only behind an internal interface (e.g. TagRepository / Tagger contract) so the trait is the only place vendor code appears.
  • Brownfield with existing tag data: do not migrate to an archived package. If tags already exist, write a mapping to the target schema and cut over once; going through Rinvex as an intermediate hop is pure cost.
  • Exit path (required): design the abstraction so tag read/write is a single service, and keep taggables semantically compatible with Spatie's taggables (taggable_type, taggable_id, tag_id). Where the schemas align, the exit is a package swap plus trait removal; where they diverge (translation tables, slug columns), it is a backfill script.

Compatibility

Verify before committing: PHP constraint, illuminate/* constraint, whether migrations use legacy or anonymous class syntax, whether translation support requires spatie/laravel-translatable at a specific major, and whether the JSON/translation columns are supported on our target DB (MySQL 5.7+ or 8, Postgres jsonb). Also verify the pivot has no foreign keys to tags — polymorphic pivots usually don't, which has downstream consequences (see Failure modes).

Sequencing

  1. Day 1–2 spike: install in a branch, tag two models, exercise create/update/delete/slug-collision/locale-fallback. Produce a compatibility verdict against our target Laravel version.
  2. Decision gate: if the spike shows any patching required and no internal maintainer exists, stop and standardize on Spatie.
  3. If proceeding: vendor the package (VCS fork into our org), pin the commit, and add it to a documented "internal forks" register with an owner.
  4. Then: build behind the Tagger contract, add integration tests covering orphan cleanup and concurrent tag creation.
  5. Defer: translated tags until a locale requirement is confirmed.

Operational Impact

Maintenance

This is the dominant cost. Archiving transfers 100% of maintenance to us: framework upgrades, security patches in the dependency chain, bug fixes, and PHP version bumps. Realistically that is a small but permanent tax — a few days per year in steady state, plus a spike at every Laravel major. It also means the package appears in our fork register, needs a CI job running its test suite against our matrix, and needs an owner in the on-call/ownership map. Compare against a maintained dependency where that work is amortized across a community.

Support

No upstream support channel, no issue triage, no maintainer to escalate to. Internal L1/L2 support must own any tagging defect end to end. Documentation on the repo will drift from our usage; the authoritative reference becomes our own README and tests. Bus factor is effectively one — whoever runs the spike.

Scaling

The pivot pattern is fine well into the millions of rows provided indexes are correct: composite index on (taggable_type, taggable_id) for "tags of this model," and (tag_id, taggable_type) for "models with this tag." Tag clouds and facet counts are the scaling trap — COUNT(*) GROUP BY tag_id over a large pivot will not hold, so plan a denormalized taggables_count on tags maintained transactionally, or push counts into the search index. Translation support adds a join per read; cache the tag vocabulary (it is small, slowly changing reference data) rather than querying per request. The package itself has no caching layer, so this is our build.

Failure modes

  • Orphaned rows: polymorphic pivots generally can't have a cascading FK. Deleting a model leaves taggables rows behind unless a model deleting hook cleans up, and the package may or may not provide it reliably. Silent data corruption that surfaces as inflated tag counts.
  • Duplicate tags under concurrency: two requests creating "Laravel" simultaneously. Only a unique index on slug (and a caught QueryException) prevents it. Confirm the published migration includes it; if not, add it.
  • Slug collisions: two distinct names slugging identically (e.g. "C++" and "C#") either merge silently or throw. Decide and test the policy.
  • Locale fallback gaps: a tag translated in en but requested in de returns empty rather than falling back, depending on the translatable config. This produces blank UI labels in production, not in tests.
  • Mass-assignment / array writes: tagging via sync-style arrays bypasses model events, so counters and search projections drift.
  • Framework upgrade breakage: the highest-probability incident. The trait's reliance on legacy Eloquent internals is exactly what Laravel majors change.

Ramp-up

Low for engineers: the API is idiomatic Laravel and the concept is universally understood, so a mid-level developer is productive in under an hour. The ramp-up cost sits with maintainers, not users — understanding the forked code well enough to patch it during a framework upgrade. Budget a half-day of knowledge transfer and a written runbook at fork time.

TPM recommendation: default to spatie/laravel-tags; adopt Rinvex only if translated tag names are a hard launch requirement that Spatie cannot meet, and only with a named internal owner, a pinned fork, and the Tagger abstraction in place from the first commit.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core