diff --git a/tools/combine b/tools/combine
new file mode 100755
index 0000000..c11872f
--- /dev/null
+++ b/tools/combine
@@ -0,0 +1,96 @@
+#!/bin/bash
+#
+# Copyright (C) 2010 Mike Gerwitz
+#
+# This file is part of ease.js.
+#
+# ease.js is free software: you can redistribute it and/or modify it under the
+# terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation, either version 3 of the License, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+# for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program. If not, see .
+# #
+
+PATH_TOOLS=$( dirname "$0" )
+PATH_LIB="$PATH_TOOLS/../lib"
+MODULE_EXT='js'
+TPL_PATH="$PATH_TOOLS/combine.tpl"
+TPL_VAR='/**{CONTENT}**/'
+
+# order matters
+CAT_MODULES="util class interface"
+
+##
+# Output template header
+##
+tpl_header()
+{
+ # cut out the top of the template (before the content location)
+ cat "$TPL_PATH" \
+ | awk "{
+ if ( \$0 == \"$TPL_VAR\" )
+ exit;
+ else
+ print \$0;
+ }"
+}
+
+##
+# Output template footer
+##
+tpl_footer()
+{
+ # cut out the bottom of the template (after where we need to place the
+ # content)
+ cat "$TPL_PATH" \
+ | awk "BEGIN { go = 0 }
+ {
+ if ( \$0 == \"$TPL_VAR\" )
+ go = 1
+ else
+ if ( go == 1 )
+ print \$0;
+ }"
+}
+
+# ensure we can locate our template (should be in the /tools dir)
+if [ ! -f "$TPL_PATH" ]; then
+ echo "Error: combine.tpl not found ($TPL_PATH)"
+ exit 1
+fi
+
+
+# output combined file header
+tpl_header
+
+# output each of the modules
+for module in $CAT_MODULES; do
+ filename="$PATH_LIB/$module.$MODULE_EXT"
+
+ if [ ! -f "$filename" ]; then
+ echo "Error: module $module not found ($filename)"
+ exit 2
+ fi
+
+ # each module must be enclosed in a closure to emulate a module
+ echo "/** $module **/"
+ echo "( function( exports )"
+ echo "{"
+
+ cat $filename
+
+ echo "} )( exports['$module'] = {} );"
+done
+
+# output combined file footer
+tpl_footer
+
+exit 0
+
diff --git a/tools/combine.tpl b/tools/combine.tpl
new file mode 100644
index 0000000..e7ec263
--- /dev/null
+++ b/tools/combine.tpl
@@ -0,0 +1,85 @@
+/**
+ * Combined redistributable ease.js file
+ *
+ * This file contains all ease.js modules in a single file for easy distribution
+ * in a browser environment.
+ *
+ * Copyright (C) 2010 Mike Gerwitz
+ *
+ * This file is part of ease.js.
+ *
+ * ease.js is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see .
+ */
+
+/**
+ * ease.js namespace
+ *
+ * All modules will be available via this namespace. In CommonJS format, they
+ * were accessed via the require() function. For example:
+ *
+ * var util = require( 'easejs' ).Class;
+ *
+ * In this file, the above would be written as:
+ *
+ * var util = easejs.Class;
+ *
+ * @type {Object}
+ */
+var easejs = {};
+
+( function( ns_exports )
+{
+ /**
+ * CommonJS module exports
+ *
+ * Since this file contains all of the modules, this will be populated with
+ * every module right off the bat.
+ *
+ * @type {Object.}
+ */
+ var exports = {};
+
+ /**
+ * Returns the requested module
+ *
+ * The require() function is likely unavailable client-side (within a web
+ * browser). Therefore, we mock one. If it is available, this overwrites it.
+ * Our modules are all preloaded in the exports object.
+ *
+ * @param {string} module_id id of the module to load
+ *
+ * @return {Object} exports of requested module
+ */
+ var require = function( module_id )
+ {
+ // remove the './' directory prefix (every module is currently included
+ // via a relative path)
+ var id_clean = module_id.substring( 2 );
+
+ // attempt to retrieve the module
+ var module = exports[ id_clean ];
+ if ( module === undefined )
+ {
+ throw "[ease.js] Undefined module: " + module_id;
+ }
+
+ return module;
+ };
+
+/**{CONTENT}**/
+
+ // the following should match the exports of /index.js
+ ns_exports.Class = exports.class;
+} )( easejs );
+