Gathering detailed insights and metrics for @chatscope/use-chat
Gathering detailed insights and metrics for @chatscope/use-chat
Gathering detailed insights and metrics for @chatscope/use-chat
Gathering detailed insights and metrics for @chatscope/use-chat
React hook for state management in chat applications.
npm install @chatscope/use-chat
Typescript
Module System
Node Version
NPM Version
TypeScript (96.86%)
JavaScript (2.95%)
Shell (0.19%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
MIT License
155 Stars
107 Commits
27 Forks
6 Watchers
2 Branches
2 Contributors
Updated on Jul 09, 2025
Latest Version
3.1.2
Package Id
@chatscope/use-chat@3.1.2
Unpacked Size
199.74 kB
Size
43.09 kB
File Count
159
NPM Version
8.11.0
Node Version
16.16.0
Published on
Sep 27, 2023
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
2
1
19
!!! Please do not use version 1.5.0 it has wrong property names !!!
React hook for state management in chat applications.
Full documentation is not available yet, but will be prepared.
If you are interested in this library and need more documentation, please let me know by adding one of the positive reactions (+1, Heart, Rocket) in the dedicated issue here: https://github.com/chatscope/use-chat/issues/1
This is a headless chat library. Think of it as something like a Formik but for chat apps.
The library can be used both with @chatscope/chat-ui-kit-react as well as with other chat components.
The goal of it is to provide a tool for handling features that are most often implemented in chat applications.
Primarily it's an application state management as well as some nice addons such as debounce or throttling of sending or receiving typing indicator signaling.
The logic of chat applications is often repetitive. Most of these applications contains a user list, a conference list and of course messages.
There are at least a few chat API providers on the market. They provide saas services that you can use to build a chat application.
You also almost always get a ready-to-use, simple messaging library from them. Such a library encapsulates a complex communication protocol.
Sometimes you also get UI components and hooks/providers that bind the UI to the provider's messaging library.
Both are closely related, which makes replacing the messaging library or UI components a lot of work.
In this case you have to take care of how to keep in your app: a list of contacts and theirs statuses, a list of messages for each contact, switching between chats, setting an active chat, rendering messages and so on...
If you create your own backed and implement the communication layer yourself, you will also not avoid doing all these things.
Isn't it better to focus on the business functionality of the application? On the layout, colour selection etc., instead of wondering how to find a message in the array to set its state to "read"?
Such things often turn out to be more complicated to do than they seem.
For example, a message list is not always a flat array. It will often be an object with messages assigned to users and conversations, and additionally, it will be grouped into blocks of incoming and outgoing messages.
Adding a message to the list requires roughly the following steps:
Uff, there is a bit of it, right?
Such things should be closed in separate logic libraries, which can be used in a simple and intuitive way. The implementation of a consistent interface also provides the possibility of internal tuning (e.g. changing the data structure) without changing the way the library is used.
Using yarn.
1yarn add @chatscope/use-chat
Using npm.
1npm install @chatscope/use-chat
The library consist of three parts:
This is a class that implements the IStorage interface. All data such as conversations, messages, current conversation indicator etc sits in the storage. BasicStorage is the basic implementation of the IStorage. It should be fully functional, and can be used for most applications. However, it is possible to write new implementations e.g. based on redux or another state library. That is why the storage is provided to ChatProvider from the outside.
This is a class that implements IChatService interface.
The purpose of this service is to maintain a connection with the chat server, send and receive messages and chat protocol commands.
This is a point that connects your chat server with the library.
To use this library, you need to write your own ChatService that implements the IChatService interface.
The implementation of the service depends on which chat server you are using.
The content of the service can be your code written from scratch, but the service also can be an encapsulation layer for any ready to use chat communication library
There is src/examples/ExampleChatService.ts available for a quick start. This is a good starting point for developing the real service for your application.
At the future I will provide more examples showing real communication with socket.io based chat server.
Service implementations for some SAAS providers will also be available.
It is a simple function that you need to implement yourself. This function receives a chat storage object (IChatStorage) as the first argument and update function as the second. This function must return an instance of the class implementing IChatService. Sometimes in your ChatService implementation, you will need to get values from the storage as well as save them to the storage. Here you can pass the storage to your service. Access to the storage state is provided by storage.getState() method. Writing to the storage is realized by calling functions such as storage.addConversation(), storage.addUser() etc. The second argument is the updateState function. Each write to the storage performed from the service needs to call the updateState function to perform re-render. For example when the service receives signalization that some user has connected, you can add user to storage using storage.addUser() method and next call updateState().
This description probably looks complicated :). But believe, me it's really simple compared to when you have to take care of everything.
This is very simple example, but it shows how easy is it to implement a chat using useChat hook.
For more complex example based on CRA please visit https://github.com/chatscope/use-chat-example. Working example app is available here: https://use-chat.examples.chatscope.io
File: index.js
1import {nanoid} from "nanoid"; 2import { 3 BasicStorage, 4 ChatProvider, 5 ExampleChatService, 6 AutoDraft 7} from "@chatscope/use-chat"; 8 9// Storage needs to generate id for messages and groups 10const messageIdGenerator = () => nanoid(); 11const groupIdGenerator = () => nanoid(); 12 13// Create serviceFactory 14const serviceFactory = (storage, updateState) => { 15 return new ExampleChatService(storage, updateState); 16}; 17 18const chatStorage = new BasicStorage({groupIdGenerator, messageIdGenerator}); 19 20export const App = () => { 21 return ( 22 <ChatProvider serviceFactory={serviceFactory} storage={chatStorage} config={{ 23 typingThrottleTime: 250, 24 typingDebounceTime: 900, 25 debounceTyping: true, 26 autoDraft: AutoDraft.Save | AutoDraft.Restore 27 }}> 28 <Chat /> 29 </ChatProvider> 30 ); 31};
File Chat.js:
1import {useState, useMemo } from "react"; 2import { MainContainer, Sidebar, ConversationList, Conversation, Avatar, MessageGroup, Message, 3 ChatContainer, ConversationHeader, MessageList, MessageInput} from "@chatscope/chat-ui-kit-react"; 4import { useChat, ChatMessage, MessageContentType, MessageDirection, MessageStatus } from "@chatscope/use-chat"; 5 6export const Chat = () => { 7 8 // Message input value 9 const [value, setValue] = useState(""); 10 11 // Get all chat related values and methods from useChat hook 12 const { 13 currentMessages, conversations, activeConversation, setActiveConversation, sendMessage, getUser 14 } = useChat(); 15 16 // Get current user data 17 const [currentUserAvatar, currentUserName] = useMemo(() => { 18 19 if (activeConversation) { 20 const participant = activeConversation.participants.length > 0 ? activeConversation.participants[0] : undefined; 21 22 if (participant) { 23 const user = getUser(participant.id); 24 if (user) { 25 return [<Avatar src={user.avatar} />, user.username] 26 } 27 } 28 } 29 30 return [undefined, undefined]; 31 32 }, [activeConversation]); 33 34 const handleSend = text => { 35 36 // Logger user (sender) 37 const currentUserId = "123"; 38 39 const message = new ChatMessage({ 40 id: "", 41 content: text, 42 contentType: MessageContentType.TextHtml, 43 senderId: currentUserId, 44 direction: MessageDirection.Outgoing, 45 status: MessageStatus.Sent 46 }); 47 48 sendMessage({ 49 message, 50 conversationId: activeConversation.id, 51 senderId: currentUserId, 52 }); 53 54 }; 55 56 return (<MainContainer> 57 <Sidebar position="left"> 58 <ConversationList> 59 {conversations.map(c => { 60 61 // Helper for getting the data of the first participant 62 const [avatar, name] = (() => { 63 64 const participant = c.participants.length > 0 ? c.participants[0] : undefined; 65 if (participant) { 66 const user = getUser(participant.id); 67 if (user) { 68 69 return [<Avatar src={user.avatar} />, user.username] 70 71 } 72 } 73 74 return [undefined, undefined] 75 })(); 76 77 return (<Conversation key={c.id} 78 name={name} 79 active={activeConversation?.id === c.id} 80 unreadCnt={c.unreadCounter} 81 onClick={e => setActiveConversation(c.id)}> 82 {avatar} 83 </Conversation>); 84 })} 85 </ConversationList> 86 </Sidebar> 87 88 <ChatContainer> 89 90 <ConversationHeader> 91 {currentUserAvatar} 92 <ConversationHeader.Content userName={currentUserName} /> 93 </ConversationHeader> 94 95 <MessageList> 96 {currentMessages.map(g => <MessageGroup key={g.id} direction={g.direction}> 97 <MessageGroup.Messages> 98 {g.messages.map(m => <Message key={m.id} model={{ 99 type: "text", 100 payload: m.content 101 }} />)} 102 </MessageGroup.Messages> 103 </MessageGroup>)} 104 </MessageList> 105 106 <MessageInput value={value} onSend={handleSend} /> 107 108 </ChatContainer> 109 110 </MainContainer>); 111}
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
license file detected
Details
Reason
no binaries found in the repo
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
no SAST tool detected
Details
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
16 existing vulnerabilities detected
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More