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

Jetstream Laravel Package

laravel-afterburner/jetstream

Laravel Afterburner for Jetstream extends Laravel Jetstream's authentication, profile, and team scaffolding with opinionated enhancements and reusable tooling, helping you build account and admin features faster with less boilerplate.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you type anything, resolve the information gap. The v1.0.0 release note is a changelog URL and nothing else — no feature list, no migration guide, no Laravel/PHP support matrix. Your first hour is discovery, not coding.

composer require laravel-afterburner/jetstream:1.0.0   # pin exact, not ^1.0
composer show laravel-afterburner/jetstream            # read requires/autoload/description
cat vendor/laravel-afterburner/jetstream/composer.json # real PHP + Laravel constraints
ls vendor/laravel-afterburner/jetstream/               # src/, config/, database/, resources/, routes/

Then enumerate what it actually registers:

php artisan about                    # providers, drivers, config summary
php artisan list | grep -i afterburner
php artisan route:list --path=teams  # confirm it hasn't shadowed Jetstream's routes

Read vendor/laravel-afterburner/jetstream/src/*ServiceProvider.php line by line before running any publish command. That file tells you the three things the README does not: which config keys exist, whether it augments Jetstream (middleware/actions) or replaces published scaffolding, and what it registers conditionally on config('jetstream.features').

Publish, then diff.

php artisan vendor:publish --provider="LaravelAfterburner\Jetstream\AfterburnerServiceProvider" --tag=config
php artisan vendor:publish --provider="LaravelAfterburner\Jetstream\AfterburnerServiceProvider"  # then: git status

Run publish on a clean branch so git status shows you exactly which files are package-owned. That diff is your "do not hand-edit" list — commit it as a marker commit.

First use case: the teams + roles + audit loop. On a scratch app, do one vertical slice end to end:

  1. Register a user, verify email, create a team.
  2. Invite a second user, accept the invitation.
  3. Assign a custom role (not the seeded owner/admin) with a narrow permission set.
  4. Confirm a member with that role sees one thing and a 403 on another.
  5. Open the audit log and confirm all four events above are recorded with actor, subject, and timestamp.

If that loop works, the package is worth evaluating further. If any step requires editing a published file, note it — that's your merge cost.

Implementation Patterns

Config-first, env-second. Every tuning knob should live in config/afterburner.php (or whatever the published file is named) with an env fallback. Resist the urge to hardcode role names or permission strings in Blade — put them in a Permissions enum or a config/permissions.php your team owns, and let the package seed from it. When the package's role model shifts in a 1.1, you change one file, not 40 views.

Authorization: three layers, one source of truth.

// Policy — the canonical check
public function update(User $user, Team $team): bool
{
    return $user->hasTeamPermission($team, 'team:update');   // verify method name in vendor
}
  • Controllers: $this->authorize('update', $team) or ->middleware('can:update,team').
  • Blade: @can('update', $team). Never @if($user->role === 'owner').
  • Inertia: share a small permissions map per team in HandleInertiaRequests so the front end can hide UI without a second round trip. Do not treat the client-side map as security — it's cosmetic.

Team scoping is the #1 source of bugs. Always resolve the team from route-model binding, never from request input:

Route::get('/teams/{team}/projects', ...)->middleware(['auth', 'can:view,team']);

Then scope every downstream query: $team->projects(), not Project::all(). Add a scopeForTeam or a global scope if the package doesn't provide one. Test it explicitly with a second user's team ID in the URL — a 403 is the expected result.

Audit logging: log the decision, not the row. The audit trail is most useful when it captures intent (who changed what, why) rather than a raw model diff. Wrap mutating operations in a transaction and let the package's model events fire inside it:

DB::transaction(function () use ($team, $data) {
    $team->update($data);                             // package observer logs it
    activity()->performedOn($team)->log('team.renamed'); // explicit, if the package exposes a helper
});

Rules that pay off later:

  • Never log passwords, tokens, 2FA secrets, or full request payloads.
  • Log the actor even for queued jobs — propagate auth()->id() into the job, or you get null actors.
  • Decide retention on day one. An audit table that only grows is a future migration you'll do at 2 a.m.

Extend Jetstream actions, don't fork them. If the package publishes app/Actions/Jetstream/* or hooks Fortify, put your logic in the action class or a listener on the domain event (TeamMemberAdded, UserUpdated), not in a controller. Overriding via a Fortify::authenticateUsing-style callback is safer than editing a published blade.

Testing pattern. Build a small trait so every team-aware test is one line:

protected function actingAsTeamMember(Team $team, array $permissions = []): User
{
    $user = User::factory()->create();
    $team->users()->attach($user, ['role' => $this->roleWith($permissions)]);
    $this->actingAs($user->fresh())->withSession(['current_team_id' => $team->id]);
    return $user;
}

Run the package's own tests against your Laravel/PHP matrix before trusting it:

vendor/bin/pest vendor/laravel-afterburner/jetstream/tests   # path per repo layout

Day-to-day loop. git pull upstream → composer update laravel-afterburner/jetstream --with-dependencies (only after reviewing the diff against your marker commit) → re-publish to a temp dir and diff -r against your app → merge manually → run the team/role/audit slice test.

Gotchas and Tips

The ownership boundary is the whole game. With 0 stars, one release, and notes that are literally a changelog link, assume nothing about BC policy. Mitigate structurally:

  • Pin "laravel-afterburner/jetstream": "1.0.0" exactly. No caret until you've survived two minors.
  • Record the adoption commit hash in the README as your fork point — the moment upstream goes quiet, you patch locally from there.
  • Add a UPGRADING.md line: "Files under X are package-owned; changes must go through a publish-diff-merge cycle."

Silent scaffolding drift. Republishing over customized auth/team views is the highest-probability, highest-impact failure. Before any vendor:publish --force, run publish into a scratch path and diff. If the package overwrites resources/views/teams/*, prefer copying the view into your app's namespace and pointing the component at your copy.

Team context leaks across boundaries. Session-stored "current team," Team::current(), and cached permission maps all go stale:

  • Queued jobs and console commands have no team context — pass team_id explicitly.
  • After changing a role, forgetCachedPermissions() (or restart the worker/clear the cache) or the user keeps old rights until TTL.
  • Listen for TeamSwitched-style events and refresh shared Inertia props there.

Route collisions. This package "works alongside Jetstream and Fortify," which means both may register /user/profile, /teams/{team}, or two-factor-challenge. If route:list shows duplicates, the last-registered provider wins — check bootstrap/providers.php / config/app.php ordering. A php artisan route:list --path=teams -v with middleware columns tells you which one you actually hit.

Debugging recipes.

  • 403 on a route you expect to pass: php artisan tinker → $user->hasTeamPermission($team, 'x'). If false, check the role→permission pivot, not the policy.
  • "Super admin can't do anything": the package may not ship a Gate::before. Add one yourself in AuthServiceProvider and short-circuit it for your admin role — but log a warning if you do.
  • Audit entries missing: observers don't fire on DB::table()->update() or mass ->update() on query builders. Use Eloquent model saves, or log explicitly.
  • Permission queries slow: check for N+1 on the role/permission pivot with DB::listen or Telescope. with('roles.permissions') on the team member listing is usually the fix.

Extension points worth knowing. Published config (tune, don't fork), custom roles/permissions seeded from your own enum, Jetstream action classes, Fortify callbacks, model observers for audit, and policies for authorization. Everything else is package-owned — treat it as third-party code you read but don't edit.

On the version number. v1.0.0 means "the API froze," not "battle-tested." Budget an ongoing small maintenance line for republish/re-merge, watch the GitHub releases feed (the notes are a link, so automate it), and re-run the vertical slice test after every bump. If a Laravel major lands and the package lags, your fork point is the escape hatch — that's why you recorded it on day one.

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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
robertmarney/lara-hierarchial-collections
simonschaufi/rule-doc-generator
emissaoja/emissaoja
blackbricksoftware/gravityforms-civicrm-form-processor
al-rahabi/fancy-crud
jinas/dhivatar-component
mltstephane/laravel-quality
bernskiold/laravel-talentlms
bernskioldmedia/laravel-form-architect