# Plain JS Introduction

Learn how to build in-app chat with the `stream-chat` [npm package](https://www.npmjs.com/package/stream-chat). It is written in vanilla JavaScript and works with any framework or none. This quickstart covers plain JavaScript.

## Start here

<Cards>
  <Card size="small" icon="rocket" title="API tour" description="Try the chat API from your browser, no setup required." href="https://getstream.io/chat/tour/" />
  <Card size="small" icon="layout" title="React tutorial" description="Prefer ready-made components? Build with Stream's React SDK." href="https://getstream.io/chat/sdk/react/tutorial/" />
  <Card size="small" icon="server" title="Server-side overview" description="Tokens, app settings and everything else that runs on your backend." href="https://getstream.io/chat/docs/javascript/server-side/" />
</Cards>

<Admonition type="note">

This SDK is the client half of your integration. App settings, permissions, webhooks, push templates and data retention are configured from your backend with a server-side SDK or the REST API, and the token your app connects with has to be signed there too. See the [server-side overview](https://getstream.io/chat/docs/javascript/server-side/) for what belongs there.

</Admonition>

## How the pieces fit together

The `stream-chat` client manages the connection, local state and API calls for your app, whatever framework it uses. Your backend doesn't render any chat, but it signs the token your app connects with and owns app-level configuration.

```mermaid
flowchart LR
  app[Your app] --> client[stream-chat client]
  client <--> api[Stream API]
  server[Your backend] --> api
  server -. user token .-> client
```

## Build with Stream CLI and Agent Skills

The [Stream CLI](https://getstream.io/cli/docs/) and [Agent Skills](https://getstream.io/agent-skills/docs/) give AI coding agents the tools and knowledge to work with Stream. There is no dedicated skill pack for JavaScript yet, but the default skills still help with live documentation and CLI-driven API work.

Install the CLI and the default skills:

```bash
curl -fsSL https://getstream.io/cli.sh | bash
getstream skills
```

Once installed, invoke `/stream` from your agent. It routes documentation lookups and API operations for you.

Stream Agent Skills can also be installed from [skills.sh](https://www.skills.sh/getstream/agent-skills/stream).

## Getting started

This guide quickly brings you up to speed on [Stream’s Chat API](https://getstream.io/chat/). The API is flexible and allows you to build any type of chat or messaging.

### Chat client

Let's get started by initializing the client and setting the current user:

```js label="JavaScript"
const client = StreamChat.getInstance("{{ api_key }}");
// you can still use new StreamChat("api_key");

await client.connectUser(
  {
    id: "jlahey",
    name: "Jim Lahey",
    image: "https://i.imgur.com/fR9Jz14.png",
  },
  "{{ chat_user_token }}",
);
```

The above snippet is for an in-browser or mobile integration. Server-side API calls are a little different, but this is covered in detail later in the documentation.

### Channels

Let’s continue by initializing your first channel. A channel contains messages, a list of people that are watching the channel, and optionally a list of members (for private conversations). The example below shows how to set up a channel to support chat for a group conversation:

```js label="JavaScript"
const client = StreamChat.getInstance("{{ api_key }}");
const channel = client.channel("messaging", "travel", {
  name: "Awesome channel about traveling",
});

// fetch the channel state, subscribe to future updates
const state = await channel.watch();
```

The first two arguments are the Channel Type and the Channel ID ( `messaging`  and  `travel`  in this case). The Channel ID is optional; if you leave it out, the ID is determined based on the list of members. The channel type controls the settings we’re using for this channel.

There are 5 default types of channels:

- livestream
- messaging
- team
- gaming
- commerce

These five options above provide you with the most sensible defaults for those use cases. You can also define custom channel types if Stream Chat defaults don’t work for your use-case.

The third argument is an object containing the channel data. You can add as many custom fields as you would like as long as the total size of the object is _less than 5KB_.

### Messages

Now that we have the channel set up, let's send our first chat message:

```js label="JavaScript"
const text = "I’m mowing the air Rand, I’m mowing the air.";

const response = await channel.sendMessage({
  text,
  customField: "123",
});
```

Similar to users and channels, the  `sendMessage`  method allows you to add custom fields. When you send a message to a channel, Stream Chat automatically broadcasts to all the people that are watching this channel and updates in real-time.

### Events

This is how you can listen to events on the clients-side:

```js label="JavaScript"
channel.on("message.new", (event) => {
  console.log("received a new message", event.message.text);
  console.log(
    `Now have ${channel.state.messages.length} stored in local state`,
  );
});
```

<Admonition type="info">

You can receive the event and access the full channel state via `channel.state` .

</Admonition>

## What's next

Now that you understand the building blocks of a fully functional chat integration, these are good places to go deeper:

<Cards>
  <Card size="small" icon="key-2" title="Tokens and authentication" description="Generate user tokens on your server and handle expiry and revocation." href="https://getstream.io/chat/docs/javascript/tokens-and-authentication/" />
  <Card size="small" icon="chat-new" title="Creating channels" description="Channel types, custom data and everything else about setting up conversations." href="https://getstream.io/chat/docs/javascript/creating-channels/" />
  <Card size="small" icon="message-2" title="Sending messages" description="Attachments, custom fields and the rest of the message API." href="https://getstream.io/chat/docs/javascript/send-message/" />
</Cards>

## FAQ

**Can I try it without my own backend?**

Yes. With the app in development mode and _Disable Authentication Checks_ toggled in the dashboard, [developer tokens](https://getstream.io/chat/docs/javascript/tokens-and-authentication/#developer-tokens) let clients connect without a token service.

**How long do tokens last?**

Indefinitely, by default. For expiring tokens, pass a [token provider](https://getstream.io/chat/docs/javascript/tokens-and-authentication/#token-providers) instead of a static string.

**Can users report messages?**

Yes. Any user can flag a message or another user, and flagged content lands in the dashboard review queue. See [moderation](https://getstream.io/chat/docs/javascript/moderation/#flag).


---

This page was last updated at 2026-09-08T17:14:07.192Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/javascript/](https://getstream.io/chat/docs/javascript/).