Go to bottom
screenshot added by Suborg on 2013-10-21 13:00:44
platform :
type :
release date : october 2013
  • rulez 2
  • is ok 2
  • sucks 0
popularity : 0%
  • rulez 0.50
alltime top: #24953
added on the 2013-10-21 12:55:20 by Suborg Suborg

popularity helper

increase the popularity of this prod by spreading this URL:

or via: facebook twitter pinterest tumblr


PunkJS is a stand-alone tool to generate compressed HTML files that can be used in the demo production from your JavaScript input source.


  • Compatibility with most Unix-like systems, no dependencies except libpng and libm
  • Selective compression using 10 different options (the smallest result is output)
  • Fast unpacking engine
  • HTML output compatible with all HTML5-enabled browsers that support <canvas> element (even IE9)
  • Robustness to sensitive characters that appear in compressed data

See README.nfo for details.
added on the 2013-10-21 13:02:29 by Suborg Suborg
How does it compare to other packers ? From your mention of Canvas, I assume it uses PNG bootstraping.

I can't/won't use this tool because it is failnux only* but thanks for providing new tools.
rulez added on the 2013-10-21 13:35:06 by p01 p01
2 p01:
If you have some toolchain like Cygwin/MSYS+MinGW, you can compile it on Faildows too. :) If anyone does a cross-compiled version (or even ports it to JS itself using Emscripten), it would be great. Maybe I'll do the latter some time later.

Compared to JsExe (you came from that thread, right?) it does not do pre-minification and other bells and whistles but does only one thing - compression - and does it well: it's far more robust (some tricks are used to prevent random garbage in PNG from breaking the parser) and the compiled HTML files were proven to work even in old (Presto-based) Opera and IE9.
It also generates dataURI-friendly output (so you can host your demos even without a hosting, but let's discuss the research on it later).
What's similar to JsExe is that there are global canvas object (Z) and 2d context (C) available to the input script right away.
After all, PunkJS is just an opensource quick proof-of-concept: all those wonders can be done with just libpng and no third-party dependencies.
added on the 2013-10-21 14:31:05 by Suborg Suborg
It would be great to see a table comparing both or more packers against the same files.

The bootstrap of PunkJS itself is quite big at ~220 bytes ( 200 when removing the onerror=src=location ) compared to the ~160 bytes we got in the global eval thread.
added on the 2013-10-21 14:51:49 by p01 p01
Do you know what onerror=src=location is for? In some browsers, it's the only way to start the bootstrap when the file is loaded from data: URL. I think you can safely omit this line if you don't need this functionality but when I export the HTML to data: URL and it stops loading, it seems really strange to me. I also know the external "for" loop could easily be dropped but it was added _just_ to support Opera/IE that fire image onload event incorrectly. This is where I prefer to spend some extra bytes to get the load process never fail, no matter the circumstances.

P.S. And yeah, getImageData in the loop body is damn slow.
added on the 2013-10-21 16:23:04 by Suborg Suborg
Ah! That's for data:uri support. Nice touch. Never used that myself but I can see the convenience.

Strange I never had loading problems in Opera, and I code my non-webGL prods in Opera 12. Was it with data:uris too ?
added on the 2013-10-21 16:40:36 by p01 p01
+ Linux
+ demotool
+ unpack engine
+ many more ...
rulez added on the 2013-10-21 16:58:00 by CHEF-KOCH CHEF-KOCH
p01, nope. I started the research of why this demo (packed with jsExe, I might add) does not work in prestOpera (12.12 and 12.16) and why it unpacks so slowly at all. Then I found this notorious "getImageData-in-a-loop" but the question of presto incompatibility still bugged me.
After that, I found out that getImageData() does work but returns a typed array full of zeroes! And then I read about a bug that when you set src and onload attributes for <img>, then prestOpera and IE show buggy behaviour: onload fires before the image is actually loaded, that's why getImageData returns only zeroes. So I decided to add an external loop that actually waits for compelte image load.

P.S. And that is why I think Presto and Trident must die, but this is offtopic...
added on the 2013-10-21 18:32:24 by Suborg Suborg
As for data: URLs, this is also a bit offtopic but I promised to tell about them. Although you can't pass them directly to tinyurl or 6g6.eu or other shortener that does no URL check (why not? you can of course, but Chrome and other WebKits will give a finger to every visitor and say ERR_UNSAFE_REDIRECT), you can create a gist, set up a simple client-redirect page like this (i call this DataWarp):
Code:<!DOCTYPE html><scr ipt>location=location.hash||"about:blank"</script>

...and then use a gist raw URL (thanks to bl.ocks.org) followed by a hash and your data: URL: http://[your.warper.url]#data:[your_data]

P.S. It's not always that simple (esp. with Chrome protection) but will do for most cases.
added on the 2013-10-21 19:09:23 by Suborg Suborg
Compared to JsExe it does not do pre-minification and other bells and whistles but does only one thing - compression - and does it well: it's far more robust (some tricks are used to prevent random garbage in PNG from breaking the parser)

What kind of tricks? If you're talking about the opening tag character checking, JsExe does it as well of course (the generated PNG is not supposed to fail half the time!)
added on the 2013-10-21 20:28:37 by cb cb
The trick is to write <!-- sequence in place of IHDR chunk length and to write --> sequence in place of IDAT CRC. These things don't seem to be checked anyway, and almost entire binary gets commented in such a way. The chance of --> sequence occuring in the compressed binary is too low to be considered (if it does, one can tweak this issue manually)
added on the 2013-10-21 20:39:10 by Suborg Suborg
Sorry, I meant IDAT chunk length but that doesn't really matter.
added on the 2013-10-21 21:18:13 by Suborg Suborg
You, clever clock with the <!-- IDAT --> trick.

The DataWarp idea is .. interesting, but I'm sure the security people at work would not approve of this.

The Presto+IE must be a regression because I'm sure I managed to watch this intro before. And I don't remember seeing a bug report about that :\
added on the 2013-10-21 21:44:20 by p01 p01
Firefox 22 and later doesn't support invalid IDAT CRC, didn't you have any problem with your parser?

Just so you know, JsExe aims to be a handy demo-oriented toolbox to produce smallest possible files (as do demo packers on other platforms). Browser compatibility isn't a top priority, even if latests versions of Chrome, FF and Opera are of course always supported. JsExe rather provides several tools to achieve the best compression ratio, while keeping reasonable compression time. As you should know any saved byte is important when you write an 1k! Anyway, JsExe and PunkJS just have different purpose.
added on the 2013-10-21 21:55:21 by cb cb
I just tweaked the bootstrap of 512 bytes by adinpsz and got it to unpack the code nicely ... but then it threw an exception in Opera 12 because of webkitAudioContext. My quickly hacked bootstrap fix was 163 bytes vs 169 bytes for the original one :p
Code:<canvas id=V><img src=# onload=C=V.getContext('2d');for(_='',$=1657;$--;_+=String.fr omCharCode(C.getImageData(0,0,1,1).data[0]))C.drawImage(this,-$,0);(1,eval)(_)> ;
added on the 2013-10-21 22:00:15 by p01 p01
Or add a null character to your PNG, use the Matraka-like bootstrapper, and save a couple bytes more :)
added on the 2013-10-21 22:12:08 by cb cb
cb, I tested PunkJS-packed minigames on Chrome/Chromium 30+, FF23 stable, FF24 stable, Opera 12.12, Opera 12.16, IE9 and IE10, no problem anywhere. Are u sure the bug was in CRC check?
added on the 2013-10-21 23:05:02 by Suborg Suborg
Btw, PunkJS output size also heavily depends on the libpng version installed in the system. While libpng 1.5 on Fedora 17 (at work) produced 1012-byte output, libpng 1.6 on Arch (at home) produced 976-byte output on the same input and with the same filter. So make sure to get as recent libpng as possible to get better compression. Probably far-future libpng 5 will collapse the script to a black hole. :D
added on the 2013-10-21 23:12:01 by Suborg Suborg

submit changes

if this prod is a fake, some info is false or the download link is broken,

do not post about it in the comments, it will get lost.

instead, click here !

[previous edits]

add a comment

Go to top