mnobre / laravel-teams
Laravel Teams is a package that provides a simple way to manage teams and their members in a Laravel application.
Requires
- php: ^8.1|^8.2
This package is not auto-updated.
Last update: 2026-02-13 23:26:45 UTC
README

Laravel Teams
Lightweight, trait-based team management for Laravel — personal teams, multi-team users, invitations and simple Blade views.
Table of contents
- Quick overview
- Installation
- Add the trait to User model
- Configuration
- Views
- Routes
- Policies & middleware
- Mail & invitations
- API reference
- Publishing & customizing
- Tests
- Contributing & license
- Quick installation checklist
Quick overview
- Composer package:
mnobre/laravel-teams - Service provider auto-discovered:
MNobre\\LaravelTeams\\LaravelTeamsServiceProvider - Views are namespaced as
teamsand published intoresources/views/teamswhen theteams-viewstag is published. - Default routes are loaded from the package
routes/teams.phpand use the plural fromconfig('teams.denomination_plural')(defaults to/teams).
Installation
- Install via Composer:
composer require mnobre/laravel-teams
- Run the installer command (recommended). This publishes config, migrations, views and the routes file for you:
php artisan laravel-teams:install
The installer publishes the following tags (manual publish examples below):
teams-config→ publishesconfig/teams.phpteams-migrations→ publishes package migrations into your appdatabase/migrationsteams-views→ publishes views intoresources/views/teamsteams-routes→ publishesroutes/teams.phpinto your app routes folder
After publishing migrations, run:
php artisan migrate
Add the trait to User model
Add the trait to your User model using the correct namespace:
use MNobre\\LaravelTeams\\Concerns\\HasTeams;
class User extends Authenticatable
{
use HasTeams;
}
The trait exposes relations and helpers used throughout the package (see API reference).
Configuration

Edit config/teams.php to adjust:
denomination_singular/denomination_plural— UI labelsroles— available role definitions for the pivotinfo— contact/social information used in the invitation email
After changing config run:
php artisan config:clear
Views
| New Team | Member Invite (Using "Team" in config) |
|---|---|
![]() | ![]() |
- Package views are provided in the package and loaded under the
teamsview namespace. - Publish views using the
teams-viewstag to copy them into your app atresources/views/teams. - Example view usage:
view('teams.index')orview('teams.invitations.accept', $data).
Note: the package shares a teamDenomination variable with all views (set in the service provider). Use teamDenomination['singular'] / ['plural'] in Blade templates.
Routes
- Routes are defined in
routes/teams.phpinside the package and are loaded by the service provider. - By default most routes are protected by
webandauthmiddleware; invitation accept/decline endpoints are public. - Public invitation endpoints:
/invitations/accept/{token}and/invitations/decline/{token}(namedteam.invitations.accept/team.invitations.decline).
Policies & middleware
MNobre\\LaravelTeams\\Policies\\TeamPolicyis registered for theTeammodel in the service provider.- Middleware alias
ensure-user-has-teamis registered and points toMNobre\\LaravelTeams\\Http\\Middleware\\EnsureUserHasTeam.
Mail & invitations
- Invitations are stored in the
team_invitationstable (modelMNobre\\LaravelTeams\\Models\\TeamInvitation). - When an invitation is created the package sends
MNobre\\LaravelTeams\\Mail\\TeamInvitationMail, which uses the Blade viewteams.invitations.emails.team-invitation. - Accepting an invitation via token may create a new user (if the invited email is not yet registered), attach the user to the team, mark the invitation accepted and switch the user's current team.

API reference
Below are the core methods implemented in the package. Use these as reference — for exact signatures check the source in src/.
HasTeams trait (attach to User)
| Method | Description |
|---|---|
currentTeam() | BelongsTo relation for the user's current team |
ownedTeams() | HasMany relation for teams the user owns |
teams() | BelongsToMany relation for memberships (pivot contains role) |
personalTeam() | Get the user's personal team (if present) |
ownsTeam(Team $team) | Check if the user owns the given team |
belongsToTeam(Team $team) | Check membership |
switchTeam(Team $team) | Set current_team_id for the user (throws if not a member) |
allTeams() | Return loaded collection of teams |
createTeam(array $data) | Create a new (non-personal) team and attach owner pivot |
createPersonalTeam() | Create a personal team and switch to it |
teamInvitations() | Relation to invitations matching the user's email |
Team model (MNobre\\LaravelTeams\\Models\\Team)
| Method | Description |
|---|---|
owner() | BelongsTo owner (user) |
users() | BelongsToMany members (pivot role) |
members() | Convenience query excluding owner |
isOwnedBy(User $user) | Check ownership |
hasUser(User $user) | Check if user is a member |
getRouteKeyName() | Uses slug for route model binding |
invitations() / pendingInvitations() | Invitation relations |
TeamInvitation model (MNobre\\LaravelTeams\\Models\\TeamInvitation)
| Method | Description |
|---|---|
isPending() / isAccepted() / isDeclined() / isExpired() | Invitation state helpers |
accept() / decline() / markAsAccepted() | Update invitation status |
Controllers
TeamController— team CRUD and switch actionsTeamMemberController— add/update/remove members and send invitationsTeamInvitationController— accept/decline/resend/cancel invitations and track pixel opens
Publishing & customizing
Publish specific resources as needed:
php artisan vendor:publish --tag=teams-config
php artisan vendor:publish --tag=teams-migrations
php artisan vendor:publish --tag=teams-views
php artisan vendor:publish --tag=teams-routes
Edit published views under resources/views/teams and published config at config/teams.php.
Tests
Tests are located under tests/. Run the test suite with your chosen runner (Pest / PHPUnit).
Contributing & license
Contributions are welcome. See repo for contribution guidelines. Licensed under MIT.
Quick installation checklist
composer require mnobre/laravel-teamsphp artisan laravel-teams:install(or publish tags manually)php artisan migrate- Add
use MNobre\\LaravelTeams\\Concerns\\HasTeams;anduse HasTeams;to yourUsermodel - Check if "Team" is the desired team denomination in
config.teams, changing this value will take immediate effect in routes (non breaking changes, simple change "teams" to the chosen name). Examples below:
| Config as "Project" | Resulting Invite (Notice "Project") |
|---|---|
![]() | ![]() |
Notes:
- The package migrations include adding a
current_team_idforeign key to youruserstable when you publish the migrations and run them. - The package does not provide global helper functions (such as
team()); use trait relations (e.g.auth()->user()->currentTeam) or the shared view variableteamDenomination.
Personal Notes:
- 👀 I’m interested in creating things
- 🌱 Always learning - PHP, Laravel, Tailwind, jQuery, HTML5, CSS3, Python, Selenium, Scraping
- 💞️ I’m looking to collaborate
- 📫 m.nobre@ymail.com



