Enabling Laravel Jetstream’s Teams Feature: Setup, Verification, and Removal
Enable Jetstream’s Teams feature via the --teams install flag or Features::teams() in config, run the migrations, verify routes and invitations, and remove it safely if needed.
25 Dec 2025, 14:17 UTC

Desired Outcome
Turn on Laravel Jetstream’s Teams feature so authenticated users can create teams, switch between them, invite members by email, and manage membership through Jetstream’s built-in UI. You will also verify the routes, database tables, and invitation flow, and learn how to remove the feature cleanly if your plans change.
A key detail up front: Teams is not a separate install command. It is a feature flag you enable either during Jetstream installation or afterwards in config/jetstream.php. Many guides get this wrong, so follow the steps below against your actual files.
Prerequisites
- A Laravel application (Laravel 10/11 with Jetstream 4.x/5.x is the common pairing; check your
composer.jsonfor exact versions). - Jetstream installed with either the Livewire or Inertia stack. If Jetstream is not installed yet, you can enable Teams during installation (see below).
- Terminal access with permission to run Artisan commands and migrate the database.
- A working mail setup (SMTP, Mailtrap, or the
logmailer) so you can test team invitation emails.
Procedure
Option A: Enable Teams during a fresh Jetstream install
If you have not installed Jetstream yet, pass the --teams flag to the stack installer. Run from the project root:
php artisan jetstream:install livewire --teams
or, for the Inertia stack:
php artisan jetstream:install inertia --teams
The installer scaffolds the team controllers, views, and migrations, and enables the feature in the published configuration.
Option B: Enable Teams on an existing Jetstream install
Open config/jetstream.php and find the features array. Uncomment or add the Teams feature entry:
'features' => [
Features::termsAndPrivacyPolicy(),
Features::profilePhotos(),
Features::api(),
Features::teams(['invitations' => true]),
Features::accountDeletion(),
],
Two things to note:
- The flag lives inside the
featuresarray asFeatures::teams()— there is no top-level'teams' => truekey. - The
'invitations' => trueoption enables email invitations. Without it, team owners can only add existing users directly.
If config/jetstream.php does not exist in your project, publish it first:
php artisan vendor:publish --provider="Laravel\Jetstream\JetstreamServiceProvider"
Then edit the features array as above. You may also need to publish the team views if you intend to customize them; check php artisan vendor:publish output for the available Jetstream tags in your version.
Run the migrations
Enabling Teams relies on migrations that create the teams, team_user (pivot), and team_invitations tables, plus team columns on users. These migration files are added to database/migrations by the installer. Apply them:
php artisan migrate
Run this where you normally run migrations (local dev, or your deployment process for staging/production). It modifies the database schema, so take a backup before running it against any database with real data.
Rebuild frontend assets
If the installer added or changed Blade/Vue components, rebuild assets from the project root:
npm install && npm run build
Use npm run dev during development instead.
Expected Checks
1. Routes are registered
Run:
php artisan route:list --path=teams
You should see team routes such as teams.create, teams.store, and teams.show (the team settings page). Also check invitation acceptance:
php artisan route:list --path=team-invitations
Exact URIs and route names vary slightly between Jetstream versions and stacks, so treat the actual output of route:list as the source of truth rather than any list in a tutorial — including this one.
2. Tables exist
Run:
php artisan migrate:status
Confirm the migrations for the teams, team_user, and team_invitations tables show as run. You can also inspect the schema directly with your database client.
3. End-to-end UI test
- Register or log in as user A. Open the team dropdown in the navigation (or the user profile page) and create a new team.
- On the team settings page, add user B’s email under “Add Team Member”. With invitations enabled, Jetstream sends an email containing an acceptance link.
- Retrieve the email (check your mail trap or
storage/logs/laravel.logif using the log mailer), log in as user B, and follow the acceptance link. - Confirm user B can switch to the shared team via the navigation dropdown and sees team-scoped content.
Limitations and Things to Watch
- Team scoping is not automatic. Jetstream provides the team model, the
current_team_idon users, and middleware, but your own models and queries must filter by the current team. A common approach is a global scope keyed on$user->current_team_id; without it, users can see each other’s data across teams. - Invitations need working mail. If mail is misconfigured, invitation records are still created in
team_invitationsbut no email arrives. Inspect that table to distinguish a mail problem from an application problem. - Route conflicts. If your application already defines routes under
/teams, checkroute:listfor duplicate URIs after enabling the feature. - Version drift. Jetstream’s scaffolding changes between major versions. Verify command names and config keys against the documentation for your installed version (
composer show laravel/jetstream).
Removing the Feature (Rollback)
Disabling Teams changes database state and removes functionality users may depend on, so plan it rather than improvising. Back up the database first.
- Export or delete team data. Decide what happens to existing teams and memberships before dropping anything.
- Disable the feature flag. Remove or comment out
Features::teams(...)from thefeaturesarray inconfig/jetstream.php. This hides the team UI and routes. - Roll back the team migrations. Identify the relevant migrations with
php artisan migrate:status, then roll back the batch(es) that created the team tables, or write a new migration that dropsteam_invitations,team_user, andteamsand removes the team columns fromusers. A forward migration is safer than a rollback on production because it is explicit and reviewable. - Remove team-specific code. Delete any customizations you made to team views, policies (
app/Policies/TeamPolicy.php), or team-scoped model logic. - Clear caches. Run
php artisan config:clearandphp artisan route:clear(or re-cache withconfig:cache/route:cache) so the disabled feature is not referenced from cached files.
After removal, verify by loading the dashboard as a user who previously belonged to a team and confirming no team menu or broken links remain.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.