Create a Meteor chat app in 30 minutes

In the previous post, we’ve discovered the very basic of Meteor. Now let’s create something interesting like this:

It’s a simple real-time chat, with many users. Follow these steps and you’ll finish it in just 30 minutes!

Where do I begin?

To create a Meteor app, simply open your terminal and run this command:

meteor create simple-chat

Now try to run your first Meteor app:

cd simple-chat

Let’s check it out using your web browser: http://localhost:3000/

You’ve told that it’s all JavaScript, why does it look so strange?

Every new Meteor app includes Blaze, which is Meteor’s built-in reactive rendering library. Usually, templates are written inSpacebars. These templates are compiled into JavaScript UI components that are rendered by the Blaze library. I’ll continue to explain it later 😀

Now add some folders like this:

This is the file structure that Meteor recommends us. You can find out more here.
Next, open client/main.html, replace all the code with this:

<title>My Simple Chat</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

We will write the body code in a new file. Let’s add some files to the imports/ui directory:

{{#each messages}}
{{> message}}
<template name="message">

and body.js

import { Template } from 'meteor/templating';
import './body.html';
messages: [
{ text: 'Hello,' },
{ text: 'Nice to meet you!' },
{ text: '<3' },

Also open file imports/ui/body.js and replace all the codes with this:

import '../imports/ui/body.js';

Then you will see something like this:

You can see that Meteor renders the HTML with head section from <head> tag in main.html, body section from <body> tag in body.html. Look at the body, you will see this:

{{#each messages}}
{{> message}}

This is Spacebar syntax. Like I’ve explained before, Spacebar is a Meteor template language. It uses statements surrounded by double curly braces such as {{#each}} and {{#if}} to let you add logic and data to your views. (You can read more aboutBlaze and Spacebar).
So in the code above, each item from the messages collection will be put into template named message. Template in Meteor is just like Partial view in ASP.NET, it’s a chunk of HTML that can be safely inserted into an existing DOM. You can define it using this:

<template name="templateName">
#put template code here

and reference in your JavaScript with Template.templateName. Furthermore, in your JavaScript, the body section can be referenced with Template.body. It’s a special “parent” template including the other child templates.
Now we have 3 messages, created by the Template.body.helpers in the body.js. So how can we can type message, send it and show in our app? We will figure out how to do it later.

Can we style it?

The easiest way is using Bootstrap. With Meteor, adding Bootstrap can be done in the blink of an eye. Open another terminal tab, go to the simple-chat directory and run this:

meteor add twbs:bootstrap

Done! Now we can use Bootstrap. Replace your body.html code with this:

<div class="container">
<div class="row">
<h3 class="text-center" >SIMPLE METEOR CHAT</h3>
<!-- text holder -->
<div class="col-md-12">
<!-- login button -->
<div class="panel panel-info">
<div class="panel-heading">
<div class="panel-body">
<ul class="media-list">
<!-- message template -->
{{#each messages}}
{{> message}}
<!-- message textbox -->
<form class="new-message">
<div class="panel-footer">
<div class="input-group">
<input type="text" name="text" class="form-control" placeholder="Enter Message" />
<span class="input-group-btn">
<button class="btn btn-info send" type="submit">SEND</button>

Then we will create several files in the imports/ui/ directory to separate each template to a different html file and js file.
Create new file message.html:

<template name="message">
<li class="media">
<div class="media-body">
<div class="media">
<a class="pull-left" href="#">
<img class="media-object img-circle img-responsive" src="" />
<div class="media-body" >

Create new file message.js:

import { Template } from 'meteor/templating';
import './message.html';

Open body.js and add this after import ‘./body.html’:

import './message.js';

Thank to Bootstrap we have such an elegant app:

Nice, but it doesn’t work, I can’t send message! Why oh why?

Don’t be too hurry! :-p . Now we will create a database collection to store the messages. Create a new file messages.js in theimports/api/ directory like this:

import { Mongo } from 'meteor/mongo';
export const Messages = new Mongo.Collection('messages');

In MongoDB, this is how we create a collection in JavaScript:

MyCollection = new Mongo.Collection("my-collection")

On the server, this sets up a MongoDB collection called my-collection; on the client, this creates a cache connected to the server collection. In this demo, to make it easy, assume that the entire database is present on the client.

We also import the messages.js to the server. Open the server/main.js and add this to the second line:

import '../imports/api/messages.js';

Now we can display message from the collection by opening body.js and replacing the Template.body.helpers with this:

import { Messages } from '../api/messages.js';
tasks() {
return Tasks.find();

Don’t worry when your chat group is empty. Just a few steps left then you will receive your messages. 😀
As we created the message textbox in the body.html in the previous step, now we will handle the submit event to insert new message. Add this to the end of the body.js:{
'submit .new-message'(event) {
// Prevent default browser form submit
// Get value from form element
const target =;
const text = target.text.value;
// Insert a message into the collection
createdAt: new Date(), // current time
//user information
// Clear form
target.text.value = '';
// scroll to last message

Now you can say Hello world!

You can open another browser window and chat to yourself to see if it works real-time. Awesome, right? 😀

Read full article

Like what you read? Give Designveloper a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.