A minimal real-time chat app demonstrating api-ape core concepts.
npm install
npm startOpen http://localhost:3000 in multiple browser windows.
ExpressJs/
├── backend.js # Express server with api-ape + onConnect hook
├── api/
│ └── message.js # Broadcast to other clients
├── index.html # Chat UI
└── styles.css # Styling
npm i api-apeconst express = require('express')
const { ape } = require('api-ape') // Server initializer (named export)
const app = express()
const server = app.listen(3000)
ape(server, {
where: 'api',
onConnect: (socket, req, send) => {
// Push history + user count on connect
const { _messages } = require('./api/message')
send('init', { history: _messages, users: ape.clients.size })
ape.publish.users({ count: ape.clients.size })
return {
onDisconnect: () => ape.publish.users({ count: ape.clients.size })
}
}
})module.exports = function (data) {
// Send to all other clients
this.clients.forEach((client) => {
if (client.clientId !== this.clientId) {
client.send('message', data)
}
})
return data // Reply to sender
}<script src="/api/ape.js"></script>
<script>
// Receive init on connect (pushed by server)
api.on('init', ({ data }) => {
console.log('History:', data.history)
console.log('Users online:', data.users)
})
// Listen for user count updates
api.on('users', ({ data }) => console.log('Online:', data.count))
// Listen for messages
api.on('message', ({ data }) => console.log(data))
// Send message
api.message({ text: 'Hello!' })
</script>| Concept | Example |
|---|---|
| Auto-wiring | ape(app, { where: 'api' }) loads api/*.js |
| onConnect hook | onConnect: (socket, req, send) => { ... } |
| Push on connect | send('init', { history, users }) |
| Publish to channel | ape.publish.users({ count }) |
| Send to specific clients | this.clients.forEach(c => c.send(...)) |
| Listen | api.on('init', handler) |
Zero dependencies: api-ape uses Node.js 24+ native WebSocket when available, otherwise a built-in RFC 6455 polyfill.