New Total.js version 2.4

Mon Feb 06 2017 22:26:50 GMT+0100 (Central European Standard Time), Peter Širka

New Total.js version 2.4

New Year brings a new version of Total.js framework v2.4. The framework is awesome tool for creating web applications, e-commerce, REST services, Internet of Things or desktop web applications running on Electron.

I have created more than 200 Total.js projects over last 4 years. Most of the projects is still up and running with great results. Give Total.js a try if you are new to Node.js, it's easy to start with.

NEW: Reusable Components

I have added a great new feature called components. Components are server-side reusable components which can contain CSS, JS and HTML in single file. The framework parses each component and splits CSS + JS to separate static files which will be merged and compiled. The framework processes HTML content as a classic view (the component has access to all view commands).

  • supports a localization markup e.g. @(Join our newsletter)
  • supports server-side scripting
  • supports (almost) all commands from views
  • CSS and JS are compiled
  • HTML is minified
  • IMPORTANT: download latest version of debug.js

Directory structure:


File structure of components:

/components/newsletter.html <!-- HTML with inline <style> (optional) and <script> (optional) -->
/components/newsletter.js   <!-- optional, its a server-side implementation (the server-side code can be implemented inline like the example below) -->

Component /components/newsletter.html:

<script type="text/totaljs">
    // This is a server-side implementation of the component (optional), the 'type="text/totaljs"' is important

    exports.install = function() {
        F.route('/api/newsletter/', json_newsletter, ['post']);

    function json_newsletter() {
        var self = this;
        self.body.ip = self.ip;
        self.body.created = F.datetime;

    .newsletter { padding: 50px; background-color: #D0D0D0; border-radius: 4px; }
    .newsletter-input { font-size: 20px; padding: 20px; width: 100%; }
    .newsletter-success { padding: 50px; background-color: green; border-radius: 4px; color: white; }

<div class="newsletter">
    <div>Join our newsletter:</div>
    <div><input type="text" class="newsletter-input" placeholder="Type your email address" /></div>

        <div>This is not a SPAM.</div>

    // This is a client-side implementaion of component (optional)

    $(document).on('keypress', '.newsletter-input', function(e) {
        if (e.keyCode !== 13)
        var el = $(this).closest('.newsletter');
        $.post('/api/newsletter/', { email: this.value }, function(response) {
            el.replaceWith('<div class="newsletter-success">THANK YOU!</div>');

Usage in views - /views/myview.html:


<!-- OR -->

<h2>Newsletter with a custom settings</h2>    
@{component('newsletter', { info: true })}; <!--info is accessible as @{} as shown above-->

Then the framework renders CSS/JS links into the @{head} / @{import('head', ...)} tag when the view contains some components.


Convertors are really helpful for converting values e.g. from String to Number when a QueryString (GET/POST+PUT+DELETE form-urlencoded) is parsed.

Create a definition file: convertors.js:

F.convert('page', Number);
F.convert('newsletter', Boolean);
F.convert('q', val => val.toLowerCase());

Some controller:

// ?page=30&limit=50&newsletter=true&search=TOTAL_FRAMEWORK
function some_action() {
    var self = this;
    console.log(typeof(; // Number
    console.log(typeof(self.query.limit)); // String (no convertor defined for limit)
    console.log(typeof(self.query.newsletter)); // Boolean
    console.log(self.query.q)); // total_framework
    self.plain('IT WORKS!');


The operations are registered asynchronous functions with a better error handling via ErrorBuilder (similar to schemas).


  • error handling
  • simple and async usage
  • global access
  • a same usage like operations in Schemas

Registering operations:

NEWOPERATION('myoperation', function(error, value, callback) {
    // error    === ErrorBuilder
    // value    === custom value
    // callback === callback([value])

    error.push('You don\'t have any privileges');    

Calling operations:

OPERATION('myoperation', { my: 'custom value (OPTIONAL)' }, function(err, response) {
    console.log(err, response);

OPERATION('another.operation', function(err, response) {
    // If the operation doesn't exist the "err" argument will contain error
    console.log(err, response);


This feature downloads and evaluates specific Total.js dependencies (controllers, modules, etc.). It uses same functionality like INSTALL() method but with additional interval argument.

Create a definition file uptodate.js:

// WebCounter module
// 5 days up-to-date interval
UPTODATE('module', '', '5 days');

// Request stats module
// 5 days up-to-date interval + update callback
UPTODATE('module', '', '5 days', function(err) {
    console.log('UPDATED', err);

// Total.js monitoring
// Custom options + 5 days up-to-date interval
UPTODATE('module', '', { url: '/$mymonitor/' }, '5 days');

// A component
// 1 day interval
UPTODATE('component', 'https://.../newsletter.html', '1 day');

// Supports event:
F.on('uptodate', function(type, name) {
    console.log('UPDATED', type, name);

Up-To-Date behaviour can also be used in /dependencies file:

module (3 days)            :

How to create e.g. up-to-date module?

  • create a module e.g. mymodule.js
  • upload your module on your server
  • link your module with your app UPTODATE('module', 'https://..../mymodule.js', '20 minutes')
  • IMPORTANT: framework cleans routes (F.route(), F.file() or F.websocket()) automatically

Content of mymodule.js:

exports.install = function(options) {
   // initialize your timers, workers, routes, etc.

exports.uninstall = function(options) {
   if (options === 'uptodate')
      console.log('UP-TO-DATE removes older version of this module');
   // clean your timers, workers, etc.   

Configuration files support custom options for dependencies

  • options is used in these methods: INSTALL() and UPTODATE()
  • and in all dependencies when they are loaded

E.g. /config:

// type#name      (Object)  : { custom options }
module#monitor    (Object)  : { url: '/$mymonitor/', token: '123456' }

ShellSort replaces QuickSort algorithm

I have performed some tests with sorting algorithms and ShellSort is about 10-15% faster than QuickSort. Note: NoSQL embedded database uses this new sorting algorithm.

X-Powered-By header

I have added back the X-Powered-By header with Total.js value (but without Total.js version). You can disable this behaviour via Total.js configuration file:

default-xpoweredby     :

// Or modify it to e.g.:
default-xpoweredby     : Brutal Framework


I have added a new String prototype String.parseTerminal([fields], fnLine(values, index, length, realIndex), [skip], [take]) for parsing terminal output.

var output = '';
output += 'total:    21109 root   11u  IPv4 413694867      0t0  TCP localhost.localdomain:8000 (LISTEN)';

output.parseTerminal(['PID', 'USER'], function(values) {
   console.log('PID:', values[0]);
   console.log('USER:', values[1]);

// or
output.parseTerminal(function(values) {
   // ['total:', '21109', 'root', '11u', 'IPv4', '413694867', '0t0', 'TCP', 'localhost.localdomain:8000', '(LISTEN)']
}, 1);

New alias for GETSCHEMA()

I have added a new alias for GETSCHEMA() method, the new alias is $$$([group], name) and it's more readable (for me). So you can choose what is better for you:

var user = $$$('User').create();
// vs.
var user = GETSCHEMA('User').create();

Improved scripting

I have improved F.script() and now it can return a compiled function.


var fn = F.script('next(value + 10)');

fn(10, function(err, response) {
    console.log(err, response); // --> null, 20

fn(100, function(err, response) {
    console.log(err, response); // --> null, 110

Mail Message supports unsubscribe method

The method adds List-Unsubscribe header.

var mail = F.mail(...);

// or
var mail = F.logmail(...);

New Year's cleaning

  • Removed restrictions (this feature can be created via middleware)
  • Removed behaviours (it wasn't as useful as expected)


  • Better performance.
  • Improved compression of CSS files.
  • A framework codebase has been optimized and decreased in size by about 8 kB.
  • The framework is ready for Node v7.
  • F.datetime has a better lifecycle.
  • Improved memory consumption in controller.memorize() and F.localize().


  • A critical bug with authorization (authorize and unauthorize flags) in WebSocket
  • JS minificator
  • Fixed streaming cache in a debug mode

Chat support $70 for 3 months

I'd like to help to answer your questions about Total.js platform, development, solving issues, etc.. All earned money will be used for Total.js platform and its products. Chat is provided by Hangouts, Gitter or Slack.

Become a sponsor

Total.js website has more than 13 K unique visitors per month and I offer you a great promoting of your company on Total.js homepage, in the partner's section and in all GitHub readme's files. Support the framework, become a sponsor. If you are interested, please contact


Follow us

Latest blogs
Flow v6 is here!
Thu Mar 07 2019 11:53:54 GMT+0100 (Central European Standard Time)
A critical security fix
Wed Feb 13 2019 22:15:39 GMT+0100 (Central European Standard Time)
New release: Total.js v3.2
Wed Feb 13 2019 22:14:39 GMT+0100 (Central European Standard Time)
Total.js Wiki v2
Fri Jan 04 2019 22:15:01 GMT+0100 (Central European Standard Time)
Total Year 2018
Thu Jan 03 2019 21:14:00 GMT+0100 (Central European Standard Time)

Latest comments
Nice tip
Mauro Junior
Thu Sep 20 2018 21:41:02 GMT+0200 (Central European Summer Time)
Not only for Total.js. You can communicate with different websocket servers.
Peter Širka
Mon Apr 23 2018 20:08:20 GMT+0200 (Central European Summer Time)
Marko: you need to create a buffer with this codepage and write byte-to-byte string. I recommend ...
Peter Širka
Mon Apr 23 2018 20:06:21 GMT+0200 (Central European Summer Time)
Is WEBSOCKETCLIENT only for internal ws connections between totaljs apps?
Stelios Stephanua
Fri Mar 16 2018 06:04:22 GMT+0100 (Central European Standard Time)
Total.js is amazing! ;)
Leonardo Hessel
Tue Dec 19 2017 19:51:15 GMT+0100 (Central European Standard Time)


Read more

Flow v6 is here!

News: We have released a new version of Flow. This version brings great new features and UI improvements.

Thu Mar 07 2019 11:53:54 GMT+0100 (Central European Standard Time)
A critical security fix

News: We were notified about the critical security bug in Total.js framework. Read a prevention.

Wed Feb 13 2019 22:15:39 GMT+0100 (Central European Standard Time)
New release: Total.js v3.2

News: This new release brings a critical security fix and small new improvements. Update Total.js now.

Wed Feb 13 2019 22:14:39 GMT+0100 (Central European Standard Time)
Total.js Wiki v2

Products: I have released a new version of Total.js Wiki. New version brings new improvements.

Fri Jan 04 2019 22:15:01 GMT+0100 (Central European Standard Time)
Total Year 2018

Business: Last year was perfect for Total.js platform. Total.js platform grows up and it has great results.

Thu Jan 03 2019 21:14:00 GMT+0100 (Central European Standard Time)
Total.js Code Editor v1

Products: Try our real-time collaboration tool for Total Developers. Code Editor offers great features for development.

Fri Dec 07 2018 22:55:13 GMT+0100 (Central European Standard Time)