Words Counter using the revealing module pattern
function bindEvents() {
  $textArea.on('keyup', updateWordsCount);
}

// $textArea keyup callback function
function updateWordsCount() {
  var text =  $textArea.val();
  var numOfChars = text.length;
  var numOfWords = countWords(text);
  $chars.html(numOfChars);
  $words.html(numOfWords);
}


The handler is unnecessarily split from the code that binds it. It's not often you see an event handler split off from it's binding. In most cases, the handler code is very specific to the binding, it cannot be reused and therefore makes no sense splitting off. Inline the handler instead.

var $textArea = $('#textArea');
var $words = $('#words'); //a span
var $chars = $('#chars'); //a span


I would discourage the use of $ indicating that a variable is a jQuery instance. Whether it's a jQuery instance, or some other constructors instance, a variable is a variable regardless of what it's bound to.

Another problem is that this piece of code isn't reusable. The selector uses an ID. IDs are supposed to be unique. That means this code can only bind to 3 unique elements, and no more. If you want to make this word counter reusable, use a class.

var flag = true;


flag is a poorly named variable. It's not telling me what it's supposed to be, what it is for, and why it is there.

// counts words for a given string
function countWords(str){
  var cnt = 0;
  var flag = true;
  for(var i = 0; i &lt; str.length; i++){
    if(str[i] !== " " &amp;&amp; flag){
      flag = false;
      cnt++; 
    }else if(str[i] === " "){
      flag = true;
    }
  }
  return cnt;
};


I think this is overcomplicated. A simple word count can be done by exploding the string into array by spaces, and getting the length of the resulting array. return str.split(' ').length what you are looking for.



For this simple task, a jQuery "plugin" would do. I would expect the plugin to accept an element containing your input and output elements, and a set of options asking for which elements are the input and output inside that group.



jQuery.fn.wordCounter = function(options){

  // For each found group
  return this.each(function(){

    // Look for the input and output under that group
    var input = $(options.input, this);
    var output = $(options.output, this);

    // Counter event and handler
    input.on('keyup', function(){
      output.text(input.val().split(' ').filter(text =&gt; text !== '').length);
    });

  });
};

$('.input-group').wordCounter({
  input: '.input-group__input',
  output: '.input-group__count',
});
&lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"&gt;&lt;/script&gt;
&lt;div class="input-group"&gt;
  &lt;input class="input-group__input"&gt;
  &lt;span class="input-group__count"&gt;
&lt;/div&gt;




In larger scale projects, consider using a small framework. vue.js, Ractive.js and riot.js are good candidates for quick-and-easy UI-related operations.