# Getting started: Pub/Sub in JavaScript
This guide will get you started with Ably Pub/Sub in JavaScript.
You'll establish a realtime connection to Ably and learn to publish and subscribe to messages. You'll also implement presence to track other online clients, and learn how to retrieve message history.
## Prerequisites
1. [Sign up](https://ably.com/signup) for an Ably account.
2. Create a [new app](https://ably.com/accounts/any/apps/new), and create your first API key in the **API Keys** tab of the dashboard.
3. Your API key will need the `publish`, `subscribe`, `presence` and `history` capabilities.
4. Create an HTML file in your project directory where you'll include the Ably JavaScript SDK via a CDN.
### (Optional) Install Ably CLI
Use the [Ably CLI](https://github.com/ably/cli) as an additional client to quickly test Pub/Sub features. It can simulate other clients by publishing messages, subscribing to channels, and managing presence states.
1. Install the Ably CLI:
```shell
npm install -g @ably/cli
```
2. Run the following to log in to your Ably account and set the default app and API key:
```shell
ably login
```
## Step 1: Connect to Ably
Clients establish a connection with Ably when they instantiate an SDK instance. This enables them to send and receive messages in realtime across channels.
Open up the [dev console](https://ably.com/accounts/any/apps/any/console) of your first app before instantiating your client so that you can see what happens.
Create an `index.html` file in your project and add the following HTML to include the Ably JavaScript SDK via CDN and establish a connection to Ably. At the minimum you need to provide an authentication mechanism. Use an API key for simplicity, but you should use [token authentication](https://ably.com/docs/auth/token.md#jwt) in a production app. A [`clientId`](https://ably.com/docs/auth/identified-clients.md) ensures the client is identified, which is required to use certain features, such as presence:
```html
Ably JavaScript Getting Started
Ably JavaScript Getting Started
```
You can monitor the lifecycle of clients' connections by registering a listener that will emit an event every time the connection state changes. Open the HTML file in your browser to see the connection message, and you can also inspect the connection event in the dev console of your app.
## Step 2: Subscribe to a channel and publish a message
Messages contain the data that a client is communicating, such as a short 'hello' from a colleague, or a financial update being broadcast to subscribers from a server. Ably uses channels to separate messages into different topics, so that clients only ever receive messages on the channels they are subscribed to.
Add the following lines to your `getStarted()` function to create a channel instance and register a listener to subscribe to the channel:
```javascript
const channel = realtimeClient.channels.get('my-first-channel');
await channel.subscribe((message) => {
log(`Received message: ${message.data}`);
});
```
Use the Ably CLI to publish a message to your first channel. The message will be received by the client you've subscribed to the channel, and be logged to the console and displayed on the page.
```shell
ably channels publish my-first-channel 'Hello!'
```
In a new terminal tab, subscribe to the same channel using the CLI:
```shell
ably channels subscribe my-first-channel
```
Publish another message using the CLI and you will see that it's received instantly by the client you have running in your browser, as well as the subscribed terminal instance.
To publish a message in your code, you can add the following line to your `getStarted` method after subscribing to the channel:
```javascript
await channel.publish('example', 'A message sent from my first client!');
```
## Step 3: Join the presence set
Presence enables clients to be aware of one another if they are present on the same channel. You can then show clients who else is online, provide a custom status update for each, and notify the channel when someone goes offline.
Add the following lines to your `getStarted()` function to subscribe to, and join, the presence set of the channel:
```javascript
await channel.presence.subscribe((member) => {
log(`Event type: ${member.action} from ${member.clientId} with the data ${JSON.stringify(member.data)}`);
});
await channel.presence.enter("I'm here!");
```
In the [dev console](https://ably.com/accounts/any/apps/any/console) of your first app, attach to `my-first-channel`. Enter a `clientId`, such as `my-dev-console`, and then join the presence set of the channel. You'll see that `my-first-client` is already present in the channel. In the console of your browser you'll see that an event was received when the dev console client joined the channel.
You can have another client join the presence set using the Ably CLI:
```shell
ably channels presence enter my-first-channel --data '{"status":"learning about Ably!"}'
```
## Step 4: Retrieve message history
You can retrieve previously sent messages using the history feature. Ably stores all messages for 2 minutes by default in the event a client experiences network connectivity issues. You can [extend the storage period](https://ably.com/docs/storage-history/storage.md) of messages if required.
If more than 2 minutes has passed since you published a regular message (excluding the presence events), then you can publish some more before trying out history. You can use the Pub/Sub SDK, Ably CLI or the dev console to do this.
For example, using the Ably CLI to publish 5 messages:
```shell
ably channels publish --count 5 my-first-channel "Message number {{.Count}}"
```
Add the following lines to your `getStarted()` function to retrieve any messages that were recently published to the channel:
```javascript
const history = await channel.history();
const messages = history.items.map((message) => message.data);
log('Message history:');
messages.forEach((message, index) => {
log(` ${index + 1}: ${JSON.stringify(message)}`);
});
```
The output will look similar to the following:
```json
[
"Message number 5",
"Message number 4",
"Message number 3",
"Message number 2",
"Message number 1"
]
```
## Next steps
Continue to explore the documentation with JavaScript as the selected language:
* Understand [token authentication](https://ably.com/docs/auth/token.md) before going to production.
* Understand how to effectively [manage connections](https://ably.com/docs/connect.md#close?lang=javascript).
* Explore more [advanced](https://ably.com/docs/pub-sub/advanced.md) Pub/Sub concepts.
You can also explore the [Ably CLI](https://www.npmjs.com/package/@ably/cli) further, or visit the Pub/Sub [API references](https://ably.com/docs/api/realtime-sdk.md).