— a JavaScript-based multi-user chat client
There are plenty of web-based chat clients out there. Most of them are built to emulate your instant messenger. They offer you tons of settings. They can join multiple networks, let you edit your profile, and even manage your message history.
Candy is different. It's built for your community.

Why Candy?

Try the Demo
It's worth more than a thousand pictures.
Demo powered by Swissjabber — a service operated by

Awesome Features!

  1. Beautiful default theme
  2. Join multiple rooms and start private conversations
  3. Get notified when new messages arrive
  4. Ignore spammers and people you don't like
  5. Moderation: Kick and ban users, change the subject of the room

Setup & Usage


Install and configure a XMPP server with HTTP binding enabled. Read our setup guides.

Due to the nature of AJAX you need to proxy the HTTP requests to the XMPP service which usually runs on a different port. The source code contains a sample .htaccess file to be used with Apache. We cover the configuration for the most used web servers here.


Download Candy and extract it in your web directory.

Getting Started

Copy example/htaccess to example/.htaccess and change the rewrite rule to point to your HTTP bind service. If you're running your XMPP host with HTTP bind service at on port 5280, the .htaccess file should look like this:

AddDefaultCharset UTF-8 Options +MultiViews RewriteEngine On RewriteRule http-bind/ [P]

If you are using nginx - copy this config: location / { root /var/www/xmpp/candy/; index index.html; location /http-bind/ { # you need to change it to your http-bind port proxy_pass; proxy_buffering off; tcp_nodelay on; } # you can use this workaround to allow nginx to send POST data to proxy_pass error_page 405 =200 $uri; }

Open your web browser and navigate to example/index.html. Make sure that you're visiting the site via Apache because it's essential that the requests to http-bind/ are redirected to your XMPP server by the .htaccess file.

You should be greeted with a login form. Enter your JID ( and password to connect to the XMPP server.


Configuring Candy is pretty simple. Take a look at the example/index.html file to get an idea how to load the libraries and to initialize Candy.

You can configure Candy by passing an object containing following options to Candy.init:

Candy.init(SERVICE, { core: { CORE_OPTIONS }, view: { VIEW_OPTIONS } });


BOSH URL of your server/proxy
Websocket URL of your server (preferably wss:// to prevent MITM)

Core Options

debug — true or false
Enable debug output to browser console.
autojoin — boolean true or an array containing rooms to auto-join: [room1,room2,...]
If set to true, Candy will follow XEP-0048 and auto-join rooms based on the bookmarks configuration of your XMPP server.
Please note: Bookmarks are supported by ejabberd and Openfire, amongst others.
For servers which don't support XEP-0048 1.0, you can explicitly list which rooms to join by passing an array such as ['jid1', 'jid2', ...]
resource — string
Set a custom resource. If not set, default is Candy.

View Options

language — language identifier, default: 'en'
Tell Candy which language pack to use. Following languages are currently delivered with the package:
  • English (en)
  • Catalan (ca)
  • Chinese (cn)
  • Czech (cs)
  • Dutch (nl)
  • French (fr)
  • German (de)
  • Hebrew (he)
  • Italian (it)
  • Japanese (ja)
  • Polish (pl)
  • Portuguese (pt)
  • Brazilian portuguese (pt_br)
  • Russian (ru)
  • Spanish (es)
  • Swedish (sv)

Please contribute your translations to the project.

assets — path to assets folder, default: 'res/'
Path to the assets folder with trailing slash.
crop — settings to crop messages & nicknames: { message: { nickname: 15, body: 1000 }, roster: { nickname: 15 } }
Messages and nicknames will be cropped to the specified lengths.
messages — object containing settings to clean up old messages: {limit: 2000, remove: 500}
If message count hits limit, remove n messages.
Because browsers are getting slower as the DOM tree grows, Candy will remove messages from each room based on this settings to keep the DOM tree at an acceptable size. You probably don't want to change the default values.
enableXHTML — enable parsing XHTML annotated XMPP messages
Using XHTML clients can format their messages in various ways. Using this flag, all your Candy users will also see nicely formatted messages.


Following example configuration will enable debugging, auto-join two rooms, and display the front end in german language:

Candy.init( '', { core: { debug: true, autojoin: ['', ''] }, view: { language: 'de' } });

Login Methods

There are six different methods to connect to a chat server:

Candy.Core.connect('jid', 'password')
Connnect as a registered user.
Connnect anonymously to a specific server. Users will be greeted with a nickname form.
Candy.Core.connect('servername', null, 'nickname')
Connect anonymously to a specific server, but don't greet the users with a login form. Instead the specified nickname will be used.
The second param (password) has to be null, because anonymous logins don't have a password (of course).
Users will be greeted with a login form. In order to authenticate they have to provide their password.
Users will be greeted with a login form. In order to authenticate they have to provide their JID ( and password.
Candy.Core.attach(jid, sid, rid)
Attach to an established session (HTTP pre-binding). This method is useful to intialize sessions at server side. Jack Moffitt, creator of Strophe, has written a nice article about pre-binding.


The user interface of Candy is very intuitive. Just take a look at the screenshot. No things to learn. No manual to read.
You might want to try the demo and get the real feeling instead.

Administrative Options

Room moderators are able to kick or ban users and change the room's subject.

Administrative usage

Getting Help

Plugins & Event Hooks

Due to the nature of JavaScript and the built-in event hooks, customizing Candy is no rocket science.


There's an official plugin repository called candy-plugins. We would like to see the number of plugins grow. Just fork it, write your own plugin and push it back into the main respository.

Download Candy Plugins and extract it in your web directory.

The Colors Plugin — An Example

Colors Plugin This plugin has originally been developed for our productive chat and because our users love it, we decided to share it with you. It's also a great example how to customize Candy.

What it does is adding a color chooser to the UI and displaying messages sent by users in their chosen colors.

To enable Colors you have to include its JavaScript code and stylesheet:

<script type="text/javascript" src="candyshop/colors/candy.js"></script> <link rel="stylesheet" type="text/css" href="candyshop/colors/candy.css" />

Finally call its init() method after Candy has been initialized:

Candy.init('/http-bind/'); CandyShop.Colors.init(); Candy.Core.connect();

Styles & Templates

We use to write our themes as plugins. The plugin folder is a good place to put your custom stylesheet into. During the process of styling you'll probably find yourself changing a template here and adding some logic there. If this happens you're already organized. Just think about it as writing a plugin that changes the appearance.

Event Hooks

Candy provides hooks that will be called during specific events which makes it easy for you to tweak and extend basic functionalities, such as displaying messages:

// candy:view.message.before-show is triggered before a chat message is displayed $(Candy).on('candy:view.message.before-show', function(evt, args) { args.message = args.message.replace(/jappix/gi, '*censored*'); // censor 'jappix' in chat messages });

Click here to see all available event hooks.

API Documentation

The API documentation of the latest version can be found here.

Under The Hood

Candy is built with JavaScript using long poll AJAX requests to emulate bidirectional-streams between client and server following the draft standard XEP-0124 of the XMPP Standards Foundation. By using this standard there are no additional requirements on client-side but having a web browser installed.

3rd Party Libraries


About Candy

Candy — abbreviation for Chats are not dead yet — was developed by Michael Weibel (@weibelm) and Patrick Stadler (@pstadler).

Fork me on GitHub