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

Tutorials Laravel Package

guava/tutorials

Guava Tutorials is a Laravel package for adding in-app tutorials and guided onboarding flows to your application. Define steps, target users, and track progress through a simple, flexible API, helping new users learn features without leaving your app. It keeps tutorial content organized and easy to...

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. guava/tutorials maps onto a well-understood Laravel package shape: service provider, publishable config/migrations/lang/views/assets, a tutorial model with ordered steps, action payloads, and user progress records. For a Laravel monolith with Blade-rendered authenticated pages, that is a native fit — no separate service, no external data store, no new vendor relationship. The package owns the scaffolding (schema, ordering, publish controls, overlay rendering); it explicitly does not own audience targeting, funnel analytics, A/B assignment, or selector validity. Those are product surfaces we would own regardless of build-vs-buy, which is the core argument for renting the scaffolding rather than building it.

The architectural risk that matters at the TPM level is not "does it work" but "where does it sit in our dependency graph." Two unknowns gate the decision:

  • Transitive surface. Whether Filament or Livewire is a hard dependency. If the package drags an admin-panel stack onto customer-facing pages, the integration cost is not the tutorial — it's the collateral. Must be answered in the spike, before content authoring.
  • Asset delivery model. Pre-built CSS/JS versus a required Vite build. This single fact determines whether theming is a config edit or a CSS fork, and therefore whether the visual layer is a 2-day or a 2-week line item.

Integration feasibility. Feasible for a timeboxed pilot. The install path is conventional (composer require, publish, migrate), and the assessment material converges on a one-to-two-developer-day spike to prove the loop end to end: define one tutorial, render it on one authenticated page, complete it, see the progress record. Productionising that same flow with real content, targeting rules, theming, and instrumentation is a sprint, not a day. The gap between those two numbers is the honest planning unit — the spike de-risks the unknowns, it does not deliver the feature.

The highest-leverage architectural decision is a thin internal boundary (TutorialRegistry or equivalent) that answers "which tutorial, if any, should this user see right now?" Every downstream consumer — Blade component, completion endpoint, analytics — talks to that boundary, never to vendor classes. This is what keeps the package an implementation detail we can swap, fork, or drop, and it is the reason a low-maturity dependency is acceptable here: exit cost is bounded by design, not by hope.

Technical risk. Ranked by expected cost:

  1. Closure serializability. 1.1.0 added Closure support to action property types. Closures are not serializable. If a closure-bearing definition lands in a cached config array or a database column, config:cache fails or silently drops it, and Octane's long-lived workers can hold stale bindings across deploys. This is a hard gate: our deployment runs config:cache, so it must be exercised in the spike, not on launch day.
  2. Selector drift. Overlays bind to DOM in our app. Every refactor of a target page is a silent breakage — no error, just a highlight that highlights nothing. No package can catch this for us. Mitigation is a convention (data-tutorial="..."), a CI assertion that every configured target exists in the rendered DOM for its page, and ideally a skip-if-missing guard implemented in our boundary.
  3. Maturity and bus factor. Single-maintainer agency package, version 1.1.0, effectively zero dependents, no stated SLA or commercial support path. None of this disqualifies use, but it does mean: named internal owner, quarterly release review and smoke test, and no placement on a business-critical surface without a fallback.
  4. Localization completeness. Persian is present, an RTL alignment fix shipped as a bug fix in a minor release, and per-locale key completeness is undocumented. Missing keys render as raw keys to users — a very visible failure. Own the translation gap rather than assuming coverage.

Key questions to close before committing.

  • PHP/Laravel version constraints, and whether Filament/Livewire is a hard transitive dependency?
  • Pre-built assets or Vite build required?
  • Does config:cache boot cleanly with closure-bearing tutorial definitions present? Does Octane?
  • Is the schema one we are willing to own — step ordering, action storage, progress keying?
  • Are route registration and middleware configurable enough to sit inside auth and inside tenancy scoping without a fork?
  • Is there a native skip-if-target-missing mechanism, or does that guard fall to us?
  • Who is the named internal owner of tutorial content and of the package itself?

Integration Approach

Stack fit. Strong for Laravel + Blade with server-rendered authenticated pages. The package's model — tutorials composed of ordered steps, each with markdown body and one or more actions (highlight, navigate, dispatch) — matches how activation flows are actually authored. It is a weaker fit if the customer surface is a heavily client-rendered SPA: the overlay would be a foreign object in our own frontend, and the "render once high in the layout" pattern has no clean analogue. Confirm the rendering target before scoping.

Migration path. There is no migration in the data sense — greenfield install, new tables, no legacy to reconcile. The migration work is organizational: tutorial content needs an authoring home (seeder or admin panel), an owner, and a review path. Treat that as a real dependency, not a follow-up. The failure mode is a package fully integrated with no content pipeline behind it.

Compatibility and configuration discipline. Everything meaningful is a config edit, not a fork: model bindings, route registration, view/component names, table names. Read the config file before writing a line of application code — it is the contract. Two rules that protect future upgrades:

  • Publish selectively. Config + migrations + lang on day one. Publish views/assets only once there is a concrete theming requirement; every published Blade view is a file that stops receiving upstream improvements and becomes a manual diff at upgrade time.
  • Extend, don't reimplement. If we swap the Tutorial model, extend the vendor class rather than rebuilding it, and re-read the vendor class after each minor upgrade to confirm table name, relationships, and ordering scope still line up.

Sequencing. Four phases, with explicit gates.

  1. Spike (1–2 dev-days). Install, publish config/migrations/lang, migrate, define one three-step tutorial ("create your first project"), render on one authenticated page, complete it, verify the progress record. Simultaneously answer the four gating questions: transitive dependency surface, asset pipeline, config:cache behavior with closures, schema acceptability. Kill criteria apply here — if any answer is a no, reassess before authoring content. Discovering a fork requirement in week three is the outcome this phase exists to prevent.
  2. Boundary and instrumentation (part of the first PR, not a follow-up). Build the registry, log its selection decision behind a debug flag (silent non-rendering is otherwise a 40-minute mystery), and fire tutorial_shown, tutorial_step_viewed, tutorial_completed, tutorial_dismissed through the existing pipeline. Retrofitting analytics means relaunching the flow to get a baseline.
  3. Content and theming (sprint). Author the pilot flow as data, adopt the data-tutorial selector convention, do one theming pass against our design system. Treat the visual layer as a theming pass, not a drop-in — an RTL alignment fix landing as a patch in a minor release is a clear signal the presentation layer is still maturing.
  4. Pilot and retire/expand decision. One low-risk flow, one page, measured against the activation milestone it targets.

Rendering placement. Register the overlay component once in the authenticated layout and let the registry decide whether anything renders. Per-page mounting invites double-mounting and makes "which tutorial wins" unanswerable.

Operational Impact

Maintenance. Low-to-moderate, and mostly ours. Pin ^1.1, review each release deliberately, budget a few hours a quarter for release review and smoke tests. The recurring tax is not the package — it's the published surface. Keep published views/assets minimal and diff against vendor versions on upgrade. Add three cheap CI checks that pay for themselves: target-selector existence per page, config:cache boot with closure definitions present (plus an Octane smoke test if we run Octane), and a visual regression baseline covering one RTL and one LTR page so an RTL fix never ships as an LTR regression.

Support. No SLA, no commercial path, single maintainer, no dependent ecosystem to lean on for community answers. Operationalize accordingly: name an internal owner (not a team — a person), document the boundary so a fork is a days-not-months decision, and contribute fixes upstream where cheap — missing translation keys are usually cheaper to upstream than to maintain as a permanent override file.

Scaling. The tutorial read path is ordinary Eloquent queries and a Blade render; it scales with the host app and introduces no new scaling axis. Two real pressure points: overlay payload weight per page render (keep closure actions pure — no queries we would not want running on every render), and progress table growth, which is bounded by users × tutorials and is trivially manageable with a firstOrCreate keyed on (tutorial, step, user) keeping duplicates out. The registry's eligibility query is the one thing worth watching as tutorials and audience rules accumulate — index accordingly.

Failure modes. Catalogued by how loudly they fail:

  • Silent, most likely: selector drift breaks an overlay with no error. Mitigated by convention + CI assertion + skip-if-missing guard in our boundary.
  • Silent, most confusing: nothing renders, no error — audience rule, publish flag, ordering, completion record, or missing selector, indistinguishable. Mitigated by the registry debug log.
  • Loud at deploy: config:cache failure or stale Octane bindings from closure-bearing definitions. Gated in the spike.
  • Visible to users: missing translation keys rendering as raw keys. Gated by per-locale key diffing before enabling a locale.
  • Gradual: published views going stale, custom model drifting from vendor expectations on upgrade. Gated by minimal publish surface and re-reading vendor classes each minor.
  • Content-shaped: step reordering silently invalidates in-flight progress; deleting a tutorial orphans completion records. Prefer a published flag over deletion so history stays legible.

Ramp-up. Shallow for any Laravel developer — the install path is conventional and the API surface is small by design. The non-obvious parts are all in this assessment, which is why the boundary wrapper and the four gating questions should be written down rather than rediscovered. Plan roughly one to two developer-days to a proven loop, a sprint to a productionised pilot, and a named owner thereafter.

Recommendation. Proceed to the timeboxed spike. The package is a credible cheap-rental option for a commodity surface — self-hosted, Laravel-native, and structurally easy to exit — provided we keep the boundary, instrument from day one, and treat the four gating questions as genuine kill criteria rather than formality. Do not place it on a business-critical surface without the named owner and fallback plan in place.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings