| title | Quickstart |
|---|---|
| description | Connect, persist a session, and send your first message in a few minutes. |
This guide walks you through creating a minimal Baileys application that connects to WhatsApp, persists your session, listens for incoming messages, and replies to them. By the end you will have a working bot you can extend with your own logic.
Baileys is an unofficial library and is not affiliated with WhatsApp. Use it responsibly and in accordance with WhatsApp's Terms of Service. The maintainers do not condone bulk messaging, spam, or stalkerware.The steps below build up to this complete working script. You can use it as a starting point for your own project.
import makeWASocket, { DisconnectReason, useMultiFileAuthState } from '@whiskeysockets/baileys'
import { Boom } from '@hapi/boom'
import qrcode from 'qrcode-terminal'
async function connectToWhatsApp() {
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
const sock = makeWASocket({
auth: state
})
sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect, qr } = update
if (qr) {
qrcode.generate(qr, { small: true })
}
if (connection === 'close') {
const shouldReconnect =
(lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('connection closed due to', lastDisconnect?.error, ', reconnecting:', shouldReconnect)
if (shouldReconnect) {
connectToWhatsApp()
}
} else if (connection === 'open') {
console.log('opened connection')
}
})
sock.ev.on('messages.upsert', async (event) => {
if (event.type !== 'notify') return
for (const m of event.messages) {
if (m.key.fromMe) continue
console.log(JSON.stringify(m, undefined, 2))
console.log('replying to', m.key.remoteJid)
await sock.sendMessage(m.key.remoteJid!, { text: 'Hello from Baileys!' })
}
})
// Save credentials whenever they are updated
sock.ev.on('creds.update', saveCreds)
}
connectToWhatsApp()Add Baileys and its `@hapi/boom` peer to your project. `@hapi/boom` is a direct dependency of Baileys and is used to inspect disconnect error codes.
<CodeGroup>
```bash npm
npm install @whiskeysockets/baileys @hapi/boom
```
```bash yarn
yarn add @whiskeysockets/baileys @hapi/boom
```
</CodeGroup>
Make sure you are running **Node.js 20.0.0 or later**. Installation will fail otherwise.
```typescript
import makeWASocket, { useMultiFileAuthState } from '@whiskeysockets/baileys'
const { state, saveCreds } = await useMultiFileAuthState('auth_info_baileys')
```
`state` holds the current credentials and keys. `saveCreds` is a callback you will pass to the `creds.update` event so the session is written to disk whenever it changes.
<Tip>
The folder name (`auth_info_baileys` in this example) can be any path you choose. Store it outside your source tree and add it to `.gitignore` — it contains long-lived cryptographic keys for your WhatsApp account.
</Tip>
```typescript
import qrcode from 'qrcode-terminal'
const sock = makeWASocket({
auth: state
})
sock.ev.on('connection.update', ({ qr }) => {
if (qr) qrcode.generate(qr, { small: true })
})
```
<Note>
When you run this for the first time, a QR code appears in your terminal. Open WhatsApp on your phone, go to **Settings → Linked devices → Link a device**, and scan the code. On subsequent runs, the saved credentials are reused and no QR code is shown.
</Note>
```typescript
import { DisconnectReason } from '@whiskeysockets/baileys'
import { Boom } from '@hapi/boom'
sock.ev.on('connection.update', (update) => {
const { connection, lastDisconnect } = update
if (connection === 'close') {
const shouldReconnect =
(lastDisconnect?.error as Boom)?.output?.statusCode !== DisconnectReason.loggedOut
console.log('connection closed due to', lastDisconnect?.error, ', reconnecting:', shouldReconnect)
if (shouldReconnect) {
connectToWhatsApp()
}
} else if (connection === 'open') {
console.log('opened connection')
}
})
```
`DisconnectReason.loggedOut` means your session was revoked (for example, you removed the linked device in the WhatsApp app). In that case, delete the auth folder and re-scan a QR code.
```typescript
sock.ev.on('messages.upsert', async (event) => {
if (event.type !== 'notify') return
for (const m of event.messages) {
if (m.key.fromMe) continue
console.log(JSON.stringify(m, undefined, 2))
console.log('replying to', m.key.remoteJid)
await sock.sendMessage(m.key.remoteJid!, { text: 'Hello from Baileys!' })
}
})
```
Filtering on `event.type === 'notify'` and `!m.key.fromMe` keeps the bot from replying to its own messages and from treating history backfills as fresh.
`m.key.remoteJid` is the WhatsApp ID (JID) of the chat the message came from — a phone number for individual chats, or a group ID for group chats. Pass it as the first argument to `sock.sendMessage` to reply.
```typescript
sock.ev.on('creds.update', saveCreds)
```
If you skip this step, your session will not be saved and you will need to scan the QR code again on every restart.
Now that you have a working connection, explore the rest of the documentation to learn what Baileys can do:
Use a pairing code instead of a QR code, or learn how to manage sessions in a database. Send text, images, video, audio, polls, reactions, and more. See the full list of events Baileys emits and what data each one carries. Create and manage groups, handle join requests, and configure ephemeral messages.