logo
version 1.2 [C++ code] [web version] adrian3/gmail

jsjuicer is a free tool for safely reducing the size of your JavaScript files. Reducing the size and number of the JavaScript files included in a web page will enable it to load faster. It is available as portable C++ code with a BSD-style licence.

  • The 1.2 release fixed a VC6 compile bug, opens the output file as binary instead of text (no \r in output) and avoids obfuscating Prototype's $ varaiable.
  • The 1.1 release added support for IE's conditional comments.

A win32 version is available. The VC8 redistributable package may be required.

As a quick overview, here is its usage statement:

usage: jsjuicer [-sdmoch] [comment] [output file] [input file]...

    -s Strip comments.
    -d Strip debug code starting with ";;;".
    -m Safely remove unneeded whitespace and control characters.
    -o Obfuscate symbols starting with "$".
    -c Inject comment.
    -h Just print this usage and exit.

    If no output file is specified then output is written to standard out.
    If no input files are specified then input is read from to standard in.
    Using -m implies -s
    Defaults to outputting the input files unmodified.

I'll explain things in a little more detail, but if you want you can jump right in by downloading the portable C++ code. Just note that your use of the program is restricted by the BSD-style licence in the code and to backup your source files because this is a one-way trip.

The command to compile with gcc is:

    g++ jsjuicer_1_2.cpp -o jsjuicer

There is also a web edition by Boris Popoff available if you want to try it out.

Why did I develop yet another JavaScript obfuscator and minimizer? For a number or reasons. I wanted something portable I could run on both Windows and Linux from the command line. I also wanted something that came with source code that I could understand and maintain, in order to be able to debug any problems I might have with the somewhat scary minimization and obfuscation process. Finally, I was worried by the dire "if you forget a semicolon or use an API symbol that isn't on our list you are toast" warnings associated with many tools. In the end it was easiest to just extend JSMin to meet these requirements. As the result is substantially different than JSMin, I'm distributing it as a new program.

jsjuicer inherits a conservative minimization engine from the excellent JSMin by Douglas Crockford. Minimization deletes characters that do not affect the interpretation of the code. These include comments tabs, spaces and linefeed characters ('\n'). In order to avoid breaking your code, linefeed characters are preserved when they may introduce implicit semicolon characters in the code. However if you follow good JavaScript programming practise and always provide explicit semicolons this usually only results in a small number of remaining linefeeds. jsjuicer adds support for expressions of the form "a + ++b" by preserving a space between two '+' or '-' symbols. JSMin currently converts it to "a+++b" which is interpreted as "a++ + b".

Obfuscation is the process of substituting very short procedurally generated symbols for the longer human readable symbols used during development. This serves a few purposes. It compresses your program by using the shortest possible names for your variables. As well, it allows the programmer to use long descriptive names while developing. This dramatically improves maintainability. Finally it makes it harder (although not impossible) to understand or reuse. The obfuscation support in jsjuicer is designed to be unable to break a working JavaScript program. It does this by only operating on identifiers which start with the '$' symbol. As long as that symbol is not added to any JavaScript API in a browser it should remain a safe transformation. Of course this requires the developer to explicitly prefix those identifiers which should be obfuscated.

Finally, jsjuicer provides support for debug-only code by removing the code following ";;;". For example:

    ;;; my_assert( x < names.length, "array access out of bounds" );
    return names[x];

All of these operations are disabled by default, and you can selectively enable or disable them in order to isolate any problems you may have. However, it is a design goal of this tool to not be able to break anything, and I will be interested to hear about any problems you are able to isolate. I can be reached at adrian3/gmail.