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 Bridge Api Laravel Package

liberusoftware/jetstream-bridge-api

An API bridge for Laravel Jetstream that exposes authentication, registration, and profile endpoints for token-based clients, making it easy to add Sanctum-powered APIs alongside Jetstream's session-based UI.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Install and confirm what you actually got.

composer require liberusoftware/jetstream-bridge-api
php artisan vendor:publish --provider="Liberu\JetstreamBridgeApi\JetstreamBridgeApiServiceProvider"

Because this package ships with zero dependents and no readable license metadata, treat the first ten minutes as an audit rather than a setup:

composer show liberusoftware/jetstream-bridge-api   # version, requires, autoload
ls vendor/liberusoftware/jetstream-bridge-api       # README, LICENSE, CHANGELOG
cat vendor/liberusoftware/jetstream-bridge-api/composer.json

If the package is a Liberu module (the module- prefix in the repo name strongly suggests it is), registration happens through modules_statuses.json / config/modules.php rather than plain package discovery. Check bootstrap/providers.php and php artisan module:list to see whether it is enabled.

2. Find the surface area before writing a line of code.

php artisan route:list --path=api -v
php artisan about

Then read, in this order:

  • routes/api.php (or routes/api/*.php) — the actual endpoints and middleware stack.
  • src/Http/Controllers — what it delegates to.
  • src/Http/Resources — the JSON shape you are committing to.
  • src/Providers/*ServiceProvider.php — bindings, config merges, route registration guards.
  • tests/ — the fastest, most truthful documentation in a package this young.

3. First use case: stand up the auth/identity endpoints for a non-Inertia client.

The whole point of a "Jetstream Bridge api presentation adapter" is to expose Jetstream/Fortify behaviour (login, registration, profile, tokens, teams) as JSON instead of Blade/Inertia responses. So your first vertical slice should be:

curl -X POST https://app.test/api/login \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"email":"[email protected]","password":"secret","device_name":"cli"}'

Getting a token back (or a clean 422 JSON validation body) tells you the adapter is wired correctly. Only after that should you touch profile or team endpoints.

4. Pin the version. With no dependents and a single release, composer.json should lock to an explicit tag, not ^1.0. You are the only integration test this package has.


Implementation Patterns

Treat the package as an adapter layer, not a domain layer. The healthy pattern is: your app owns the domain actions, Jetstream/Fortify owns the auth mechanics, and this package owns the presentation — turning those results into resources, status codes, and validation envelopes. Keep business rules out of the adapter.

Headless backend for a mobile or SPA client. The canonical workflow:

// routes/api.php (your app) — extend, don't fork
Route::middleware('auth:sanctum')->group(function () {
    Route::get('/me', fn (Request $r) => new \App\Http\Resources\UserResource($r->user()));
});

Consume the bridge's session/token endpoints for auth, then layer your own application resources on top. Never let the client talk directly to a package resource you don't control — wrap it, so a package update can't silently change your public contract.

Token issuance via Sanctum, not Passport. Check config/sanctum.php and the HasApiTokens trait on App\Models\User. If the adapter calls $user->createToken($request->device_name), your request payload must include device_name, or you'll get a 500 from a null argument rather than a validation error.

Version-pin your API in the route prefix. If the package registers routes without a version segment, wrap them in your own group:

Route::prefix('v1')->group(function () {
    $this->loadRoutesFrom(base_path('routes/api.php'));
});

This costs nothing now and saves a coordinated client release later.

Delegate to Fortify actions where the adapter allows it. If the package exposes a JetstreamBridge facade or contract, rebind it in your own service provider so custom registration (invite codes, tenant assignment, feature flags) still runs:

$this->app->bind(
    \Liberu\JetstreamBridgeApi\Contracts\RegistersUsers::class,
    \App\Actions\RegisterTenantUser::class
);

This is the intended extension point for anything beyond stock Jetstream. If no such contract exists, that is your signal to fork the controller rather than monkey-patch it.

Testing pattern. Use Sanctum::actingAs($user) for authenticated endpoint tests and RefreshDatabase. Assert on the JSON structure with assertJsonStructure, not exact payload matching — the adapter is the most likely thing to change between releases.

it('returns the authenticated profile', function () {
    Sanctum::actingAs(User::factory()->create());
    $this->getJson('/api/user')
         ->assertOk()
         ->assertJsonStructure(['data' => ['id', 'name', 'email']]);
});

Pair it with the sibling module-jetstream-bridge. The API adapter almost certainly expects the bridge package's contracts and config to be present. Install both, and read the bridge's migrations/models first — the adapter's resources will mirror them.


Gotchas and Tips

The license is NOASSERTION. This is the single biggest risk and it is not a technical one. Before this goes anywhere near a commercial product, get written clarification from the maintainer or your legal team. NOASSERTION means Composer could not identify a license — not that it is permissive.

Zero stars, zero dependents, one release. You are the canary. Vendor the package (composer require then copy into packages/ with a path repository) if you need to patch it, and subscribe to the repo's releases. Do not assume a security fix is coming.

Release date metadata reads as 2026-10-26. That is in the future relative to any normal audit. Treat it as a publishing anomaly and verify the actual tag/commit date with composer show -a before trusting the version.

Route collisions. Laravel's default api prefix, Sanctum's /sanctum/csrf-cookie, and any existing routes/api.php entries can collide with what the adapter registers. Run php artisan route:list --path=api before and after installing, and diff the output. Duplicate URIs fail silently — the last registered route wins, which is rarely the one you want.

JSON vs. redirect responses. Jetstream is built around redirects on success and ValidationException on failure. A presentation adapter has to force Accept: application/json behaviour. If you get 302 instead of 422, the client is not sending Accept: application/json, or the adapter's exception handler isn't registered. Add it explicitly in bootstrap/app.php:

->withExceptions(function (Exceptions $exceptions) {
    $exceptions->shouldRenderJsonWhen(fn ($request) => $request->is('api/*'));
})

CSRF for SPA vs. tokens for mobile. Cookie-based SPA auth requires the /sanctum/csrf-cookie round-trip and matching SANCTUM_STATEFUL_DOMAINS. Token auth for mobile skips it. Mixing the two produces the classic 419 Page Expired on one client and 401 Unauthenticated on the other. Pick one per client and document it.

Config caching hides everything. php artisan config:cache after installing will freeze whatever the package merged at boot. If routes or bindings "disappear" in staging but work locally, run php artisan optimize:clear first — this accounts for a large share of "the package is broken" reports with modular packages.

Middleware and rate limiting. Check whether the adapter registers its own named limiter (RateLimiter::for('api', ...)). If not, /api/login is a brute-force target. Add a limiter yourself in AppServiceProvider — this is a gap the package will not close for you.

Version drift with Jetstream/Fortify. Because the adapter mirrors Fortify's request/response shapes, a Fortify minor release can break it. Constrain laravel/fortify and laravel/jetstream in composer.json, and add a smoke test hitting each auth endpoint so a composer update fails in CI rather than in production.

Where to extend safely. Prefer, in order: (1) rebinding a published contract, (2) middleware around the package routes, (3) your own controller that reuses the package's form requests and resources, (4) a fork. Editing files under vendor/ is never the answer — it will be wiped on the next composer install and nobody will remember why it mattered.

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.
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
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin