Build From Scratch or Integrate Seamlessly
Whether you're starting a new project or enhancing an existing application, Replyke adapts to your needs. Use it as a complete social infrastructure or add individual features—without vendor lock-in, migrations, or architectural rewrites.
Flexible Foundation
Start with what you need, scale to what you want. Build a complete social platform or add a single feature—Replyke grows with your vision.
Zero Migration Required
Existing app? Keep your data models, auth systems, and architecture intact. New project? Get a production-ready foundation without complex setup.
Progressive Integration
Choose your level of adoption. Use Replyke as your entire backend, just the social features, or anywhere in between—without all-or-nothing commitments.
Complete Control
Export your data anytime. Remove Replyke later if needed—your project stays functional and fully yours. No lock-in, ever.
Works Your Way
Available for React, React Native, vanilla JavaScript, and Node.js. Use our packages for seamless integration or connect via our REST API for maximum flexibility.
Production-Ready, Risk-Free
Test features without permanent commitments. For new projects, get battle-tested infrastructure. For existing apps, enhance without disrupting what works.
Build a complete social platform from the ground up, or add powerful features to your existing application—all while maintaining complete control over your data, architecture, and future decisions.
Build Social Features, Fast
Production-ready React hooks and components. No backend complexity, no infrastructure headaches. Just clean APIs that work out of the box.
Zero-Config Authentication
Wrap once with ReplykeProvider, then call useAuth() for instant sign-up / sign-in / sign-out logic with email and password.
Replyke also supports easy integration with your existing user system or any external authentication systems you wish to integrate.
1import { ReplykeProvider, useAuth, useUser } from "@replyke/react-js";23 function App() {4 return (5 <ReplykeProvider projectId="your-project-id">6 <AuthenticatedApp />7 </ReplykeProvider>8 );9 }1011 function AuthenticatedApp() {12 const { signUpWithEmailAndPassword, signInWithEmailAndPassword, signOut } = useAuth();13 const { user } = useUser();14 const [email, setEmail] = useState("");15 const [password, setPassword] = useState("");1617 const handleSignUp = async () => {18 try {19 await signUpWithEmailAndPassword({20 email,21 password,22 username: email.split("@")[0], // Generate username from email23 name: "Demo User"24 });25 } catch (error) {26 console.error("Sign up failed:", error);27 }28 };2930 const handleSignIn = async () => {31 try {32 await signInWithEmailAndPassword({ email, password });33 } catch (error) {34 console.error("Sign in failed:", error);35 }36 };3738 return user ? (39 <div>40 <p>Welcome, {user.username}!</p>41 <button onClick={signOut}>Sign Out</button>42 </div>43 ) : (44 <div>45 <input46 type="email"47 placeholder="Email"48 value={email}49 onChange={(e) => setEmail(e.target.value)}50 />51 <input52 type="password"53 placeholder="Password"54 value={password}55 onChange={(e) => setPassword(e.target.value)}56 />57 <button onClick={handleSignUp}>Sign Up</button>58 <button onClick={handleSignIn}>Sign In</button>59 </div>60 );61 }Dynamic Content Feeds
useEntityList() streams content with built-in pagination, real-time filtering, and sorting. Redux-powered state management handles infinite scroll, content filters, and optimistic updates automatically.
Already have exisiting content data? No problem - you can leverage Replyke's content streaming capabilities to score, filter and stream your existing data.
1import { useEntityList, EntityProvider } from "@replyke/react-js";23 function ContentFeed() {4 const {5 entities,6 loading,7 hasMore,8 loadMore,9 fetchEntities10 } = useEntityList({11 listId: "home-feed"12 });1314 // Initialize the feed with basic configuration15 useEffect(() => {16 fetchEntities({17 sortBy: "hot"18 }, {19 sourceId: "user-posts",20 limit: 1021 });22 }, []);2324 const handleFilterByContent = (keyword: string) => {25 fetchEntities({26 sortBy: "hot",27 keywordsFilters: { includes: [keyword] }28 }, { resetUnspecified: true });29 };3031 const handleFilterByTime = (timeFrame: string) => {32 fetchEntities({33 sortBy: "hot",34 timeFrame: timeFrame35 }, { resetUnspecified: true });36 };3738 return (39 <div>40 <div className="filters">41 <button onClick={() => handleFilterByContent("javascript")}>42 JavaScript Posts43 </button>44 <button onClick={() => handleFilterByContent("react")}>45 React Posts46 </button>47 <button onClick={() => handleFilterByTime("week")}>48 This Week49 </button>50 <button onClick={() => handleFilterByTime("month")}>51 This Month52 </button>53 </div>5455 <div className="feed">56 {entities.map(entity => (57 <EntityProvider key={entity.id} entity={entity}>58 <PostCard />59 </EntityProvider>60 ))}61 </div>6263 {hasMore && (64 <button onClick={loadMore} disabled={loading}>65 {loading ? "Loading..." : "Load More"}66 </button>67 )}68 </div>69 );70 }Dual-Style Comments
Choose between SocialCommentSection and ThreadedCommentSection for different UX styles.
Both include nested replies, likes/votes, @mentions, voting and GIF support out-of-the-box.
Intrested in a custom comments UI? No problem - all Replyke comments components are built with composability in mind and can be customized to fit your exact needs.
1import {2 SocialCommentSection,3 ThreadedCommentSection4 } from "@replyke/comments-social-react-js";56 function CommentsDemo({ entity }: { entity: Entity }) {7 const [style, setStyle] = useState<"social" | "threaded">("social");89 return (10 <div>11 <div className="style-selector">12 <button13 onClick={() => setStyle("social")}14 className={style === "social" ? "active" : ""}15 >16 Social Style17 </button>18 <button19 onClick={() => setStyle("threaded")}20 className={style === "threaded" ? "active" : ""}21 >22 Threaded Style23 </button>24 </div>2526 {style === "social" ? (27 <SocialCommentSection28 entity={entity}29 callbacks={{30 loginRequiredCallback: () => showLoginModal(),31 }}32 />33 ) : (34 <ThreadedCommentSection35 entity={entity}36 highlightedCommentId={urlParams.commentId}37 callbacks={{38 loginRequiredCallback: () => showLoginModal()39 }}40 />41 )}42 </div>43 );44 }Optimistic Voting
EntityProvider + useEntity() gives instant UI feedback with vote states, counts, and user interaction flags.
Replyke handles optimistic updates and server sync automatically, so you can focus on the user-experience knowing that the data is taken care of.
1import { EntityProvider, useEntity } from "@replyke/react-js";23 function PostWithVoting({ entity }: { entity: Entity }) {4 return (5 <EntityProvider entity={entity}>6 <PostCard />7 </EntityProvider>8 );9 }1011 function PostCard() {12 const {13 entity,14 userUpvotedEntity,15 userDownvotedEntity,16 upvoteEntity,17 removeEntityUpvote,18 downvoteEntity,19 removeEntityDownvote20 } = useEntity();2122 const handleUpvote = () => {23 if (userUpvotedEntity) {24 removeEntityUpvote();25 } else {26 upvoteEntity();27 }28 };2930 const handleDownvote = () => {31 if (userDownvotedEntity) {32 removeEntityDownvote();33 } else {34 downvoteEntity();35 }36 };3738 return (39 <div className="post-card">40 <h3>{entity?.title}</h3>41 <p>{entity?.content}</p>4243 <div className="voting-controls">44 <button45 onClick={handleUpvote}46 className={userUpvotedEntity ? "active" : ""}47 >48 ▲ {entity?.upvotes.length}49 </button>50 <button51 onClick={handleDownvote}52 className={userDownvotedEntity ? "active" : ""}53 >54 ▼ {entity?.downvotes.length}55 </button>56 </div>57 </div>58 );59 }User Profiles & Social Graph
View user profiles with bio, birthdate, and social actions — all with optimistic updates.
useFollowManager() handles one-sided follows/unfollows.
useConnectionManager() manages two-sided connections (requests and approvals, like friendships on Facebook or LinkedIn).
1import { useFollowManager, useFetchUser, useUser } from "@replyke/react-js";23 function UserProfile({ userId }: { userId: string }) {4 const { user: currentUser } = useUser();5 const { isFollowing, isLoading, toggleFollow } = useFollowManager({ userId });6 const [profileUser, setProfileUser] = useState(null);7 const [loading, setLoading] = useState(true);89 const fetchUser = useFetchUser();1011 useEffect(() => {12 const loadProfile = async () => {13 try {14 setLoading(true);15 const user = await fetchUser({ userId });16 setProfileUser(user);17 } catch (error) {18 console.error("Failed to fetch user profile:", error);19 } finally {20 setLoading(false);21 }22 };2324 if (userId) {25 loadProfile();26 }27 }, [userId, fetchUser]);2829 if (loading) {30 return <div className="loading">Loading profile...</div>;31 }3233 if (!profileUser) {34 return <div className="error">Profile not found</div>;35 }3637 return (38 <div className="profile">39 <div className="profile-header">40 <img41 src={profileUser.avatar || "/default-avatar.png"}42 alt={profileUser.username + " avatar"}43 className="avatar"44 />45 <div className="profile-info">46 <h2>@{profileUser.username}</h2>47 {profileUser.name && <p className="name">{profileUser.name}</p>}48 </div>4950 {currentUser && currentUser.id !== userId && (51 <button52 onClick={toggleFollow}53 disabled={isLoading}54 className={isFollowing ? "btn-following" : "btn-follow"}55 >56 {isLoading ? "..." : isFollowing ? "Following" : "Follow"}57 </button>58 )}59 </div>6061 <div className="profile-details">62 {profileUser.bio && (63 <div className="bio">64 <h3>Bio</h3>65 <p>{profileUser.bio}</p>66 </div>67 )}6869 {profileUser.birthdate && (70 <div className="birthdate">71 <h3>Born</h3>72 <p>{new Date(profileUser.birthdate).toLocaleDateString("en-US", {73 month: "long",74 day: "numeric",75 year: "numeric"76 })}</p>77 </div>78 )}7980 <div className="join-date">81 <h3>Joined</h3>82 <p>{new Date(profileUser.createdAt).toLocaleDateString("en-US", {83 month: "long",84 year: "numeric"85 })}</p>86 </div>87 </div>88 </div>89 );90 }Smart Collections
useLists() enables hierarchical collections with navigation, creation, and management. useIsEntitySaved() provides bookmark states. Perfect for organizing content with Redux-powered persistence.
With these hooks, users can create nested collections, save items, and navigate their organizational structure seamlessly - increasing engagement and retention.
1import { useLists, useIsEntitySaved, useEntity } from "@replyke/react-js";23 function CollectionsManager() {4 const { entity } = useEntity();5 const {6 currentList,7 subLists,8 loading,9 createList,10 deleteList,11 updateList,12 addToList,13 removeFromList,14 isEntityInList,15 openList,16 goBack17 } = useLists();1819 const { checkIfEntityIsSaved } = useIsEntitySaved();20 const [newListName, setNewListName] = useState("");21 const [editingList, setEditingList] = useState(null);2223 const handleCreateList = async () => {24 if (!newListName.trim()) return;25 await createList({ listName: newListName.trim() });26 setNewListName("");27 };2829 const handleSaveToCollection = async () => {30 if (!entity) return;3132 if (isEntityInList(entity.id)) {33 await removeFromList({ entityId: entity.id });34 } else {35 await addToList({ entityId: entity.id });36 }37 };3839 return (40 <div className="collections-manager">41 {currentList && (42 <div className="navigation">43 <button onClick={goBack}>← Back to {currentList.parentName}</button>44 <h3>{currentList.name}</h3>45 </div>46 )}4748 <div className="current-entity-actions">49 {entity && (50 <button51 onClick={handleSaveToCollection}52 className={isEntityInList(entity.id) ? "saved" : ""}53 >54 {isEntityInList(entity.id) ? "✓ Saved" : "+ Save to Collection"}55 </button>56 )}57 </div>5859 <div className="collections-list">60 {subLists.map(list => (61 <div key={list.id} className="collection-item">62 <div onClick={() => openList(list)} className="collection-info">63 📁 {list.name} ({list.entityIds.length} items)64 </div>65 <button onClick={() => setEditingList(list.id)}>Edit</button>66 <button onClick={() => deleteList({ list })}>Delete</button>67 </div>68 ))}69 </div>7071 <div className="create-collection">72 <input73 value={newListName}74 onChange={(e) => setNewListName(e.target.value)}75 placeholder="New collection name"76 onKeyDown={(e) => e.key === "Enter" && handleCreateList()}77 />78 <button onClick={handleCreateList} disabled={!newListName.trim()}>79 Create Collection80 </button>81 </div>82 </div>83 );84 }In-app Notifications
useAppNotifications() provides notificatitons data, unread notification counts and mark-as-read functionality.
Interested in customizing the noitfications text? Simply pass a notification templates object with your custom formats.
By notifying users of important events related to them, your product will experience increased engagement and retention.
1import { useAppNotifications, AppNotification } from "@replyke/react-js";23 function NotificationCenter() {4 const {5 appNotifications,6 unreadAppNotificationsCount,7 loading,8 hasMore,9 loadMore,10 markNotificationAsRead,11 markAllNotificationsAsRead12 } = useAppNotifications({13 limit: 15,14 notificationTemplates: {15 entityComment: {16 title: "New comment on your post",17 content: "$initiatorName commented: '$commentContent'"18 },19 commentReply: {20 title: "Reply to your comment",21 content: "$initiatorName replied to your comment"22 },23 entityUpvote: {24 title: "Your post was liked",25 content: "$initiatorName liked your post '$entityTitle'"26 },27 newFollow: {28 title: "New follower",29 content: "$initiatorName started following you"30 },31 entityMention: {32 title: "You were mentioned",33 content: "$initiatorName mentioned you in a post"34 }35 }36 });3738 const handleNotificationClick = (notification: AppNotification.UnifiedAppNotification) => {39 if (!notification.isRead) {40 markNotificationAsRead(notification.id);41 }4243 // Navigate based on notification type44 switch (notification.type) {45 case "entity-comment":46 navigate("/posts/" + notification.metadata.entityShortId);47 break;48 case "new-follow":49 navigate("/users/" + notification.metadata.initiatorId);50 break;51 case "entity-upvote":52 navigate("/posts/" + notification.metadata.entityShortId);53 break;54 }55 };5657 return (58 <div className="notification-center">59 <div className="notification-header">60 <h3>61 Notifications62 {unreadAppNotificationsCount > 0 && (63 <span className="unread-badge">{unreadAppNotificationsCount}</span>64 )}65 </h3>66 {unreadAppNotificationsCount > 0 && (67 <button onClick={markAllNotificationsAsRead}>68 Mark All Read69 </button>70 )}71 </div>7273 <div className="notifications-list">74 {appNotifications.map(notification => (75 <div76 key={notification.id}77 onClick={() => handleNotificationClick(notification)}78 className={"notification-item" + !notification.isRead ? "unread" : ""}79 >80 <div className="notification-content">81 <h4>{notification.title}</h4>82 <p>{notification.content}</p>83 <span className="timestamp">84 {formatTimestamp(notification.createdAt)}85 </span>86 </div>87 {!notification.isRead && <div className="unread-indicator" />}88 </div>89 ))}90 </div>9192 {hasMore && (93 <button onClick={loadMore} disabled={loading}>94 {loading ? "Loading..." : "Load More"}95 </button>96 )}97 </div>98 );99 }Built-in Moderation & Safety Tools
Building user-generated content platforms means dealing with moderation. Replyke handles the complex safety infrastructure so you can focus on building great experiences.
User Reporting System
Built-in reporting functionality allows users to flag inappropriate content instantly.
Developer Hooks
Easy-to-use hooks let you implement custom reporting on any entities in your app.
Centralized Dashboard
Manage all reports, remove content, and moderate users from one unified interface.
User Management
Ban users for flexible timeframes or indefinitely with comprehensive user controls.
Content Oversight
Review, approve, or remove user-generated content to maintain community standards.
Safe Communities
Build trust and safety into your platform from day one with proven moderation tools.
1import { useCreateReport } from "@replyke/react-js";23function ReportPostDialog({ entityId }: { entityId: string }) {4 const createReport = useCreateReport({ type: "entity" });56 const handleSubmitReport = async (reason: string) => {7 await createReport({8 targetId: entityId,9 reason10 });11 };1213 return (14 <select onChange={(e) => handleSubmitReport(e.target.value)}>15 <option value="">Report content...</option>16 <option value="spam">Spam</option>17 <option value="harassment">Harassment</option>18 <option value="inappropriate">Inappropriate</option>19 </select>20 );21}Focus on building your platform while Replyke ensures your community stays safe, engaged, and free from harmful content.
Securely add email and password authentication or integrate third-party login systems to get users onboard effortlessly.
Add threaded comments with upvotes, downvotes, and mentions, creating engaging discussions across your content.
Deliver personalized feeds with filtering, sorting, and time-based options to keep users engaged and informed.
Boost engagement with upvotes and downvotes while automatically scoring posts to deliver smarter, more engaging feeds.
Notify users instantly about votes, mentions, replies and more, driving real-time interaction and engagement.
Empower users to organize content with lists and sub-lists tailored to their needs.
Create personalized user experiences with customizable profiles that showcase avatars, bios, and more.
Empower users to report inappropriate content while you manage reports from a centralized dashboard.
Pricing & Plans
Choose the plan that's right for you or start free and upgrade later. No hidden fees, no surprises.
Free $0 Per month | Hobby $15 Per month | Pro $25 Per month | Growth $75 Per month | |
|---|---|---|---|---|
| Dashboard Seats | 1 | 1 | 2 | 5 |
| Monthly Active Users (MAU) | 500 | 5k | 25k | 100k |
| Records stored (entities, comments, notifications, lists) | 50k | 500k | 5M | 25M |
| API Calls | 250k/month | 2M/month | 10M/month | 40M/month |
| Egress (Data Transfer Out) | 1GB | 20GB | 80GB | 320GB |
| Storage | DB 1GB + Files 1GB | DB 3GB + Files 5GB | DB 10GB + Files 25GB | DB 30GB + Files 100GB |
| Back-office & Moderation Dashboard | ||||
| Get Started → | Get Started → | Get Started → | Get Started → |
$0
/month$15
/month$25
/month$75
/monthDashboard Seats
Monthly Active Users (MAU)
Records stored (entities, comments, notifications, lists)
API Calls
Egress (Data Transfer Out)
Storage
Back-office & Moderation Dashboard
Need more than our Growth plan?
We offer custom pricing for high-volume applications and enterprise customers. Let's discuss a plan that fits your specific requirements.