Skip to main content
The Socket.io client provides real-time, bidirectional communication between the client and server. It automatically listens to service events and supports all standard service methods.

Installation

npm install @feathersjs/client socket.io-client

Browser Usage

1

Include the libraries

<script src="//unpkg.com/@feathersjs/client@^5.0.0/dist/feathers.js"></script>
<script src="//cdn.socket.io/4.5.4/socket.io.min.js"></script>
2

Connect to the server

const socket = io('http://localhost:3030')
const app = feathers()
3

Configure Socket.io client

app.configure(feathers.socketio(socket))
4

Use services with real-time events

const messages = app.service('messages')

// Listen for real-time events
messages.on('created', message => {
  console.log('New message:', message)
})

// Create a message
await messages.create({
  text: 'Hello from the client!'
})

Node.js Usage

import feathers from '@feathersjs/client'
import socketio from '@feathersjs/socketio-client'
import { io } from 'socket.io-client'

// Connect to the server
const socket = io('http://localhost:3030')
const app = feathers()

// Configure Socket.io client
app.configure(socketio(socket))

// Use services
const messages = app.service('messages')

// Listen for real-time events
messages.on('created', message => {
  console.log('New message:', message)
})

messages.on('updated', message => {
  console.log('Message updated:', message)
})

messages.on('removed', message => {
  console.log('Message removed:', message)
})

// Call service methods
const newMessage = await messages.create({
  text: 'Hello, world!'
})

Service Methods

All standard Feathers service methods work over Socket.io:
const messages = app.service('messages')

// Find - emits 'find' event
const results = await messages.find({
  query: {
    read: false,
    $limit: 10
  }
})

// Get - emits 'get' event
const message = await messages.get(1)

// Create - emits 'create' event
const created = await messages.create({
  text: 'New message',
  userId: 1
})

// Update - emits 'update' event
const updated = await messages.update(1, {
  text: 'Updated message',
  userId: 1,
  read: true
})

// Patch - emits 'patch' event
const patched = await messages.patch(1, {
  read: true
})

// Remove - emits 'remove' event
const removed = await messages.remove(1)

Real-time Events

The Socket.io client automatically listens to service events. When any service method is called (by any client or the server), all connected clients receive the corresponding event:
const messages = app.service('messages')

// Listen for created events
messages.on('created', message => {
  console.log('Someone created a message:', message)
})

// Listen for updated events
messages.on('updated', message => {
  console.log('Someone updated a message:', message)
})

// Listen for patched events
messages.on('patched', message => {
  console.log('Someone patched a message:', message)
})

// Listen for removed events
messages.on('removed', message => {
  console.log('Someone removed a message:', message)
})

Event Listener Management

Manage event listeners using standard EventEmitter methods:
const messages = app.service('messages')

// Add listener
const onCreated = message => {
  console.log('New message:', message)
}
messages.on('created', onCreated)

// Remove specific listener
messages.off('created', onCreated)

// Remove all listeners for an event
messages.removeAllListeners('created')

// Remove all listeners for all events
messages.removeAllListeners()

// Listen once
messages.once('created', message => {
  console.log('First message:', message)
})

EventTarget Compatibility

The client also supports the EventTarget API:
const messages = app.service('messages')

messages.addEventListener('created', (event) => {
  console.log('New message:', event.detail)
})

messages.removeEventListener('created', handler)

Socket.io Connection Options

You can configure the Socket.io connection with various options:
import { io } from 'socket.io-client'

const socket = io('http://localhost:3030', {
  // Reconnection options
  reconnection: true,
  reconnectionDelay: 1000,
  reconnectionAttempts: 10,

  // Connection timeout
  timeout: 20000,

  // Transport options
  transports: ['websocket', 'polling'],

  // Path
  path: '/socket.io/',

  // Authentication
  auth: {
    token: 'your-auth-token'
  },

  // Extra headers (for initial HTTP handshake)
  extraHeaders: {
    'Authorization': 'Bearer token'
  }
})

const app = feathers()
app.configure(feathers.socketio(socket))

Connection Events

Listen to Socket.io connection events:
const socket = io('http://localhost:3030')

// Connection established
socket.on('connect', () => {
  console.log('Connected to server')
  console.log('Socket ID:', socket.id)
})

// Connection lost
socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason)
})

// Reconnection attempts
socket.on('reconnect_attempt', (attempt) => {
  console.log('Reconnection attempt:', attempt)
})

// Reconnected
socket.on('reconnect', (attemptNumber) => {
  console.log('Reconnected after', attemptNumber, 'attempts')
})

// Connection error
socket.on('connect_error', (error) => {
  console.log('Connection error:', error.message)
})

const app = feathers()
app.configure(feathers.socketio(socket))

Custom Methods

Socket.io client supports custom service methods:
import feathers from '@feathersjs/client'
import socketio from '@feathersjs/socketio-client'
import { io } from 'socket.io-client'

const socket = io('http://localhost:3030')
const app = feathers()
const connection = socketio(socket)

app.configure(connection)

// Register service with custom methods
app.use('todos', connection.service('todos'), {
  methods: ['find', 'get', 'create', 'patch', 'customMethod']
})

const todos = app.service('todos')

// Call custom method
const result = await todos.customMethod({ data: 'value' })

Direct Service Usage

You can create service instances without configuring the app:
import socketio from '@feathersjs/socketio-client'
import { io } from 'socket.io-client'

const socket = io('http://localhost:3030')
const connection = socketio(socket)

// Create a service directly
const messagesService = connection.service('messages')

// Listen to events
messagesService.on('created', message => {
  console.log('New message:', message)
})

// Use the service
const messages = await messagesService.find()

Error Handling

Handle errors from Socket.io service calls:
import { errors } from '@feathersjs/client'

const messages = app.service('messages')

try {
  const message = await messages.get(999)
} catch (error) {
  console.log(error.code) // 404
  console.log(error.message) // 'Not Found'
  console.log(error.className) // 'not-found'
  console.log(error.data) // Additional error data

  // Check error type
  if (error instanceof errors.NotFound) {
    console.log('Message not found')
  }
}

// Handle service-specific errors
messages.on('error', error => {
  console.error('Service error:', error)
})

Accessing the Socket Instance

The socket instance is available on the app:
const socket = io('http://localhost:3030')
const app = feathers()

app.configure(feathers.socketio(socket))

// Access the socket
console.log(app.io.connected) // true/false
console.log(app.io.id) // socket ID

// Manually disconnect
app.io.disconnect()

// Manually reconnect
app.io.connect()

TypeScript Support

The Socket.io client has full TypeScript support:
import { feathers } from '@feathersjs/client'
import socketio, { SocketService } from '@feathersjs/socketio-client'
import { io } from 'socket.io-client'
import type { CustomMethod } from '@feathersjs/feathers'

interface Message {
  id: number
  text: string
  userId: number
  read: boolean
}

interface ServiceTypes {
  messages: SocketService<Message> & {
    customMethod: CustomMethod<{ result: string }>
  }
}

const socket = io('http://localhost:3030')
const app = feathers<ServiceTypes>()
const connection = socketio<ServiceTypes>(socket)

app.configure(connection)

const messages = app.service('messages')

// Typed event listener
messages.on('created', (message: Message) => {
  console.log(message.text)
})

// Typed service calls
const message: Message = await messages.get(1)

React Example

Using Socket.io client in a React application:
import { useEffect, useState } from 'react'
import feathers from '@feathersjs/client'
import socketio from '@feathersjs/socketio-client'
import { io } from 'socket.io-client'

const socket = io('http://localhost:3030')
const app = feathers()
app.configure(socketio(socket))

function MessageList() {
  const [messages, setMessages] = useState([])

  useEffect(() => {
    const messageService = app.service('messages')

    // Load initial messages
    messageService.find().then(setMessages)

    // Listen for new messages
    const onCreated = message => {
      setMessages(current => [...current, message])
    }

    const onRemoved = message => {
      setMessages(current => 
        current.filter(m => m.id !== message.id)
      )
    }

    messageService.on('created', onCreated)
    messageService.on('removed', onRemoved)

    // Cleanup
    return () => {
      messageService.off('created', onCreated)
      messageService.off('removed', onRemoved)
    }
  }, [])

  return (
    <div>
      {messages.map(message => (
        <div key={message.id}>{message.text}</div>
      ))}
    </div>
  )
}

Next Steps

REST Client

Learn about HTTP-based connections

Authentication

Add authentication to your Socket.io client

Build docs developers (and LLMs) love