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

Stream Laravel Laravel Package

get-stream/stream-laravel

Official Laravel integration for GetStream.io activity feeds. Add scalable news feeds, follow relationships, notification feeds, and real-time updates to Laravel apps with Eloquent model integration, a Stream facade, config publishing, and a Laravel notification channel.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and wire it into Laravel:

composer require getstream/stream-laravel

php artisan vendor:publish --provider="GetStream\StreamLaravel\StreamServiceProvider"

Register the service provider and facade if your Laravel version does not auto-discover them:

// config/app.php
'providers' => [
    GetStream\StreamLaravel\StreamServiceProvider::class,
],

'aliases' => [
    'Stream' => GetStream\StreamLaravel\Facades\Stream::class,
],

Set credentials in .env:

STREAM_API_KEY=your_key
STREAM_API_SECRET=your_secret
STREAM_APP_ID=your_app_id
STREAM_REGION=us-east

Then clear cached config:

php artisan config:clear

Look first at config/stream.php, the Stream facade, and the underlying getstream/stream-php client docs. This package is primarily a thin Laravel wrapper: config binding, service provider, and facade access to the Stream PHP client.

A good first use case is writing an activity to a user feed and reading it back:

use GetStream\StreamLaravel\Facades\Stream;

Stream::feed('user', (string) $user->id)->addActivity(
    'post',
    (string) $post->id,
    [
        'actor' => 'user:'.$user->id,
        'message' => $post->title,
        'foreign_id' => 'post:'.$post->id,
        'time' => $post->created_at->toIso8601String(),
    ]
);

$activities = Stream::feed('timeline', (string) $user->id)->getActivities();

If the facade methods differ in your installed version, inspect the resolved client:

dd(app('stream'));

Implementation Patterns

Write activities from domain events, not controllers. Keep feed writes in listeners or jobs so posting, commenting, liking, and following all update Stream consistently.

// app/Listeners/AddPostActivity.php
public function handle(PostCreated $event): void
{
    Stream::feed('user', (string) $event->post->user_id)->addActivity(
        'post',
        (string) $event->post->id,
        [
            'actor' => 'user:'.$event->post->user_id,
            'message' => $event->post->title,
            'foreign_id' => 'post:'.$event->post->id,
            'time' => $event->post->created_at->toIso8601String(),
        ]
    );
}

Use follow relationships for timelines. A common pattern is a personal user feed plus a timeline feed that follows other users:

Stream::feed('timeline', (string) $user->id)
    ->follow('user', (string) $followedUser->id);

Stream::feed('timeline', (string) $user->id)
    ->unfollow('user', (string) $followedUser->id);

Then render timeline:{id} in the UI. For fan-out-on-write, keep feed slugs stable (user, timeline, notification, group) and always cast IDs to strings.

Use foreign_id and time for idempotency. These let you update/remove activities reliably and avoid duplicate entries when jobs retry:

Stream::feed('user', (string) $user->id)
    ->removeActivity('post:'.$post->id, true);

Queue Stream writes and use afterCommit. Feed calls are network calls; doing them synchronously in model observers can slow requests and create inconsistent state if the transaction rolls back.

class SyncPostToStream implements ShouldQueue
{
    use InteractsWithQueue, Queueable;

    public $afterCommit = true;
}

Reactions and comments are usually handled through the underlying client’s reactions API. Keep reaction writes in the same queued listener pattern and store your local comment/reaction ID as the activity or reaction foreign_id where possible.

Eloquent integration depends on version. Older releases shipped traits for syncing models to feeds; newer releases are thinner. Before relying on model traits, check the installed package source. If traits are absent, wire created, updated, and deleted model events to queued jobs yourself.

Testing: avoid real Stream calls in tests. Bind a fake client into the container or mock the facade, then assert that expected feed/activity calls were made. Also assert that jobs are dispatched rather than executing network calls inline.

Stream::shouldReceive('feed')
    ->with('user', '1')
    ->andReturn($fakeFeed);

Integration tip: keep a small application-level service around the facade for feed naming and payload shaping. That gives you one place to change when the package or stream-php API changes.

Gotchas and Tips

  • This is a thin wrapper. Most behavior, method signatures, and errors come from getstream/stream-php. Check both package versions with composer show getstream/stream-laravel getstream/stream-php.
  • Version compatibility matters. The last release is from 2023; verify PHP, Laravel, and stream-php compatibility before adopting it in a new Laravel 10/11 project. Because the wrapper is small, replacing the binding with your own client is often straightforward.
  • Config caching bites. After changing STREAM_* values, run php artisan config:clear. In production, deploy config changes through your normal cache rebuild.
  • Never expose the API secret client-side. Use server-side calls or server-generated user tokens for client SDKs. The Laravel package should run only on the server.
  • app_id and region must match the Stream app. Mismatched region/app ID usually surfaces as authentication or not-found errors that look like credential problems.
  • Feed IDs are strings. Passing integers inconsistently can create feeds that look identical in logs but are different resources. Cast with (string) at the boundary.
  • Use foreign_id deliberately. It is your idempotency and deletion key. Establish a convention such as post:{id}, comment:{id}, and reaction:{id}.
  • Avoid synchronous Stream calls in model observers. They add latency to requests and can fail inside transactions. Queue them after commit and add retries/backoff.
  • Handle Stream outages gracefully. Wrap feed reads in try/catch where the UI can degrade, and do not let feed-write failures break core business transactions.
  • Rate limits and timeouts are real. Batch where possible, avoid N+1 feed calls in loops, and consider caching rendered feed pages.
  • Facade alias collisions. Stream is a generic alias; if another package uses it, register the full facade class or rename the alias.
  • Debug with Tinker. app('stream'), config('stream'), and a single feed(...)->getActivities() call will quickly distinguish config, auth, and method-signature problems.
  • No built-in fake/testing story is guaranteed. Plan to mock the facade or bind a fake client rather than assuming Laravel-style HTTP fakes exist.
  • Zero dependents and modest stars mean limited ecosystem support. Treat this as a small integration layer, pin versions, and be prepared to use getstream/stream-php directly if the wrapper lags behind Laravel releases.
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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle