RequireJS for WebGL and Coffeescript

Feb. 19, 2012

I have been writing a bunch of WebGL code over the last year, and I got a bit into Coffeescript. What has always bothered me is how messy it is to create structured applications. A major part of that is that JS has no module system. The following post presents a way to deal with the issue.


Code and Demo

The code for this solution is hosted on github. And here is a demo.

The problem

You want to write a structured web application, but Javascript has no modules. To make matters worse, if you write WebGL, you also want to write shaders. They are tedious to get into your application and do not support includes.

One way to deal with this is to just pollute your html file with script tags, and to globally load all shaders with some preprocessing step. But that means that the code using a shader is usually far from where the shader gets loaded, and the binding is tedious to type.


A clever package to deal with the module problem in Javascript is RequireJS. It makes it possible to use the require method to load in packages, and to define modules.

So all scripts and shaders will get resolved using RequireJS, which greatly simplifies managing them.


To kick off compiling you can type

make compile


The tool finds all .coffee files, and automatically wraps them in a RequireJS define (i.e. makes them a module) and writes them to the debug folder.


Shaders are compiled to javascript files that declare their dependencies, file location and source lines with line numbers.

Files ending with .shader are compiled assuming they're going to produce shader programs. Files ending with .glsl are assumed to be shader includes.

If a coffeescript file needs to get a shader, it can directly require it and call the "create" method with the webgl context. This will resolve the shader includes and produce a ready to use object.


All files are first written to the directory debug. This makes debugging the javascript produced by coffeescript easier.

Shader files are also validated, and if there is a compile error, the filename from where the error stems as well as the line number and source line are reported on the error console.

Packing for release

make pack

A useful tool for RequireJS is r.js, a static resolver that produces a single file from the dependencies of the code.

In order to avoid having to use require.js to load the code, almond.js is prepended by the packer.

Modify Reload

In order to avoid having to type make all the time, you can use the command:

make watch

This automatically looks out for modified files and compiles/packs them automatically

Cleaning up builds

Use the command

make clean

To cleanup generated files.


The code for this project serves as an example on how to use it, check it out on github.