import { FeedsClient } from "@stream-io/feeds-react-sdk";
const client = new FeedsClient("<API key>");
await client.connectUser({ id: "john" }, "<user token>");
// Create a feed (or get its data if exists)
const feed = client.feed("user", "john");
// Subscribe to WebSocket events for state updates
await feed.getOrCreate({ watch: true });
// Add activity
await feed.addActivity({
text: "Hello, Stream Feeds!",
type: "post",
});Quick Start
Stream lets you build activity feeds at scale. The largest apps using Stream have over 100 Million users. Stream Activity Feeds scales effectively while giving you more flexibility over the content shown in your feed.
Stream Feeds has two halves. Feed groups, ranking, permissions and push setup are configured on your backend with a server-side SDK, authenticated with your API secret. The code you ship to your users is a client SDK, and it connects with a token signed on that backend. Whichever half you are here for, this sidebar carries an overview of the other.
Getting Started
For SDK-accurate examples generated from the OpenAPI spec, use the Stream snippets reference: TypeScript SDK - Feeds API. Replace node in the URL with the SDK language you want to inspect.
import (
"context"
"log"
"github.com/GetStream/getstream-go/v4"
)
client, err := getstream.NewClient("api_key", "api_secret")
if err != nil {
log.Fatal(err)
}
feedsClient := client.Feeds()
feed := feedsClient.Feed("user", "john")
// Get or create the feed
feedResponse, err := feed.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error getting/creating feed:", err)
}
log.Printf("Response: %+v\n", feedResponse)
// Add activity to the specific feed
response, err := feedsClient.AddActivity(context.Background(), &getstream.AddActivityRequest{
Feeds: []string{feedResponse.Data.Feed.Feed},
Type: "post",
Text: getstream.PtrTo("Hello, Stream Feeds!"),
UserID: getstream.PtrTo("john"),
})
log.Printf("Response: %+v\n", response)Key Concepts
Activities
Activities are the core content units in Stream Feeds. They can represent posts, photos, videos, polls, and any custom content type you define.
Feeds
Feeds are collections of activities. They can be personal feeds, timeline feeds, notification feeds, or custom feeds for your specific use case.
Real-time Updates
Stream Feeds provides real-time updates through WebSocket connections, ensuring your app stays synchronized with the latest content.
Social Features
Built-in support for reactions, comments, bookmarks, and polls makes it easy to build engaging social experiences.
Server-side vs client-side
Most API calls can be made client-side. Client-side API calls use the permission system. Server-side API calls have full access.
Most apps will default to making API calls client-side. Engineers will often use server-side to do the following tasks:
- Updating feed groups or feed views for ranking and aggregation
- Syncing users
- Returning tokens for authenticating users
- Writing to feeds that do not belong to the current user (since the user does not have access client side to do this)
Common Use Cases
Social Media Feed
feedsClient := client.Feeds()
// Create timeline feed
timeline := feedsClient.Feed("timeline", "john")
_, err = timeline.GetOrCreate(context.Background(), &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error getting/creating feed:", err)
}
// Add a reaction to activity
addReactionResponse, err := feedsClient.AddReaction(context.Background(), "activity_123", &getstream.AddReactionRequest{
Type: "like",
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Response: %+v\n", addReactionResponse)
// Add comment to activity
addCommentResponse, err := feedsClient.AddComment(context.Background(), &getstream.AddCommentRequest{
Comment: "Great post!",
ObjectID: "activity_123",
ObjectType: "activity",
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Response: %+v\n", addCommentResponse)
// Add a reaction to comment
addCommentReactionResponse, err := feedsClient.AddCommentReaction(context.Background(), addCommentResponse.Data.Comment.ID, &getstream.AddCommentReactionRequest{
Type: "love",
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Response: %+v\n", addCommentReactionResponse)Notification Feed
feedsClient := client.Feeds()
// Create a notification feed
feedResponse, err := feedsClient.GetOrCreateFeed(context.Background(), "notification", "john", &getstream.GetOrCreateFeedRequest{
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal(err)
}
log.Printf("Response: %+v\n", feedResponse)Polls
// Create a poll
pollResponse, err := client.CreatePoll(context.Background(), &getstream.CreatePollRequest{
Name: "What's your favorite Go feature?",
Options: []getstream.PollOptionInput{
{Text: getstream.PtrTo("Goroutines")},
{Text: getstream.PtrTo("Channels")},
{Text: getstream.PtrTo("Interfaces")},
},
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error creating poll:", err)
}
log.Printf("Poll Response: %+v\n", pollResponse)
// Add activity with poll
feedsClient := client.Feeds()
pollActivity, err := feedsClient.AddActivity(context.Background(), &getstream.AddActivityRequest{
Feeds: []string{"user:john"},
Text: getstream.PtrTo("Check out this poll!"),
Type: "post",
UserID: getstream.PtrTo("john"),
PollID: getstream.PtrTo(pollResponse.Data.Poll.ID),
})
if err != nil {
log.Fatal("Error adding activity:", err)
}
log.Printf("Response: %+v\n", pollActivity)
// Cast a vote on a poll
voteResponse, err := feedsClient.CastPollVote(context.Background(), pollActivity.Data.Activity.ID, pollResponse.Data.Poll.ID, &getstream.CastPollVoteRequest{
Vote: &getstream.VoteData{
OptionID: getstream.PtrTo(pollResponse.Data.Poll.Options[0].ID),
},
UserID: getstream.PtrTo("john"),
})
if err != nil {
log.Fatal("Error casting vote:", err)
}
log.Printf("Response: %+v\n", voteResponse)Advanced Features
Custom Activity Types
Create custom activity types to represent your app's specific content:
// Add custom activity
feedsClient := client.Feeds()
response, err := feedsClient.AddActivity(context.Background(), &getstream.AddActivityRequest{
Type: "workout",
Feeds: []string{"user:john"},
Text: getstream.PtrTo("Just finished my run"),
UserID: getstream.PtrTo("john"),
Custom: map[string]any{
"distance": 5.2,
"duration": 1800,
"calories": 450,
},
})
if err != nil {
log.Fatal("Error adding activity:", err)
}
log.Printf("Response: %+v\n", response)Real-time Updates with State Layer
Only for client-side SDKs
const feed = client.feed("user", "john");
// Subscribe to WebSocket events for state updates
await feed.getOrCreate({ watch: true });
// Read state reactively with hooks
const { activities } = useFeedActivities(feed) ?? {};