diff --git a/gulpfile.helper.js b/gulpfile.helper.js
new file mode 100644
index 0000000000000000000000000000000000000000..d494849e8762ecb39039f60021c6f7b4ef4a8af0
--- /dev/null
+++ b/gulpfile.helper.js
@@ -0,0 +1,153 @@
+
+var $ = require('gulp-load-plugins')()
+var minimist = require('minimist')
+
+module.exports = function (gulp, helperOptions) {
+  var options = minimist(process.argv.slice(2), {
+    string: ['modulename', 'export', 'name', 'testport', 'testfiles', 'regenerator'],
+    default: {
+      modulename: helperOptions.moduleName,
+      targetName: helperOptions.targetName,
+      export: 'ignore',
+      testport: '8888',
+      testfiles: 'src/**/*.js',
+      regenerator: process.version < 'v0.12'
+    }
+  })
+
+  var files = {
+    src: helperOptions.polyfills.concat(helperOptions.concatOrder.map(function (f) {
+      return 'src/' + f
+    })),
+    test: ['build/Helper.spec.js'].concat(helperOptions.concatOrder.map(function (f) {
+      return 'build/' + f
+    }).concat(['build/**/*.spec.js']))
+  }
+
+  if (options.regenerator) {
+    files.test = helperOptions.polyfills.concat(files.test)
+  }
+
+  var babelOptions = {
+    loose: 'all',
+    modules: 'ignore',
+    experimental: true
+  }
+  if (!options.regenerator) {
+    babelOptions.blacklist = 'regenerator'
+  }
+
+  gulp.task('dist', function () {
+    return gulp.src(files.src)
+      .pipe($.sourcemaps.init())
+      .pipe($.concat(options.targetName))
+      .pipe($.babel({
+        loose: 'all',
+        modules: 'ignore',
+        experimental: true
+      }))
+      .pipe($.uglify())
+      .pipe($.sourcemaps.write('.'))
+      .pipe(gulp.dest('./dist/'))
+  })
+
+  gulp.task('watch:dist', function () {
+    gulp.src(files.src)
+      .pipe($.watch(files.src))
+      .pipe($.sourcemaps.init())
+      .pipe($.concat(options.targetName))
+      .pipe($.babel({
+        loose: 'all',
+        modules: 'ignore',
+        experimental: true
+      }))
+      // .pipe($.uglify())
+      .pipe($.sourcemaps.write('.'))
+      .pipe(gulp.dest('./dist/'))
+  })
+
+  gulp.task('build', function () {
+    return gulp.src('src/**/*.js')
+      .pipe($.sourcemaps.init())
+      .pipe($.babel(babelOptions))
+      .pipe($.sourcemaps.write())
+      .pipe(gulp.dest('build'))
+  })
+
+  gulp.task('watch:build', function () {
+    gulp.src('src/**/*.js')
+      .pipe($.watch('src/**/*.js'))
+      .pipe($.sourcemaps.init())
+      .pipe($.babel(babelOptions))
+      .pipe($.sourcemaps.write())
+      .pipe(gulp.dest('build'))
+  })
+
+  gulp.task('updateSubmodule', function () {
+    return gulp.src('./package.json', {read: false})
+      .pipe($.shell([
+        'git submodule update --init'
+      ]))
+  })
+
+  gulp.task('bump', function () {
+    var bumptype
+    return gulp.src(['./package.json', './dist/package.json', './dist/bower.json'], {base: '.'})
+      .pipe($.prompt.prompt({
+        type: 'checkbox',
+        name: 'bump',
+        message: 'What type of bump would you like to do?',
+        choices: ['patch', 'minor', 'major']
+      }, function (res) {
+        bumptype = res.bump
+      }))
+      .pipe($.bump({type: bumptype}))
+      .pipe(gulp.dest('./'))
+  })
+
+  gulp.task('publish', ['test', 'updateSubmodule', 'bump', 'dist'], function () {
+    return gulp.src('./package.json', {read: false})
+      .pipe($.prompt.confirm({
+        message: 'Are you sure you want to publish this release?',
+        default: false
+      }))
+      .pipe($.shell([
+        'cp ./README.md ./dist/',
+        'standard',
+        'echo "Deploying version <%= getVersion(file.path) %>"',
+        'git pull',
+        'cd ./dist/ && git add -A',
+        'cd ./dist/ && git commit -am "Deploy <%= getVersion(file.path) %>" -n',
+        'cd ./dist/ && git push',
+        'cd ./dist/ && git tag -a v<%= getVersion(file.path) %> -m "Release <%= getVersion(file.path) %>"',
+        'cd ./dist/ && git push origin --tags',
+        'git commit -am "Release <%= getVersion(file.path) %>" -n',
+        'git push'
+      ], {
+        templateData: {
+          getVersion: function (s) {
+            return require(s).version
+          }
+        }
+      }))
+  })
+
+  gulp.task('dev:node', ['test'], function () {
+    gulp.watch('src/**/*.js', ['test'])
+  })
+
+  gulp.task('dev:browser', ['watch:build'], function () {
+    return gulp.src(files.test)
+      .pipe($.watch(['build/**/*.js']))
+      .pipe($.jasmineBrowser.specRunner())
+      .pipe($.jasmineBrowser.server({port: options.testport}))
+  })
+
+  gulp.task('test', ['build'], function () {
+    return gulp.src(files.test)
+      .pipe($.jasmine({
+        verbose: true,
+        includeStuckTrace: true
+      }))
+  })
+}
diff --git a/gulpfile.js b/gulpfile.js
index 3d95236cd813c6b6214353d71ff6c76934107893..68d93f313d6d1742611f1fce93bf3aaf01225656 100644
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -44,6 +44,8 @@
 */
 
 var gulp = require('gulp')
+var $ = require('gulp-load-plugins')()
+var runSequence = require('run-sequence').use(gulp)
 
 require('./gulpfile.helper.js')(gulp, {
   polyfills: ['./node_modules/gulp-babel/node_modules/babel-core/node_modules/regenerator/runtime.js'],
@@ -67,15 +69,45 @@ require('./gulpfile.helper.js')(gulp, {
   moduleName: 'yjs'
 })
 
-gulp.task('default', ['test'])
-
-gulp.task('copy:dist', function () {
-  return gulp.src(['../y-*/dist/*.js', '../y-*/dist/*.js.map'])
+gulp.task('dev:examples', ['updateSubmodule', 'watch:dist'], function () {
+  // watch all distfiles and copy them to bower_components
+  var distfiles = ['./dist/*.js', './dist/*.js.map', '../y-*/dist/*.js', '../y-*/dist/*.js.map']
+  gulp.src(distfiles)
+    .pipe($.watch(distfiles))
+    .pipe($.rename(function (path) {
+      var dir = path.dirname.split('/')[0]
+      console.log(JSON.stringify(path))
+      path.dirname = dir === '.' ? 'yjs' : dir
+    }))
     .pipe(gulp.dest('./dist/Examples/bower_components/'))
-})
 
-gulp.task('dev:examples', ['dist', 'copy:dist'], function () {
-  gulp.watch('src/**/*.js', ['copy:dist'])
+  return $.serve('dist/Examples/')()
+})
 
-  return $.serve('dist/Examples')()
+gulp.task('default', function (cb) {
+  gulp.src('package.json')
+    .pipe($.prompt.prompt({
+      type: 'checkbox',
+      name: 'tasks',
+      message: 'Which tasks would you like to run?',
+      choices: [
+        'test                    Test this project',
+        'dev:examples            Serve the examples directory in ./dist/',
+        'dev:browser             Watch files & serve the testsuite for the browser',
+        'dev:nodejs              Watch filse & test this project with nodejs',
+        'bump                    Bump the current state of the project',
+        'publish                 Publish this project. Creates a github tag',
+        'dist                    Build the distribution files'
+      ]
+    }, function (res) {
+      var tasks = res.tasks.map(function (task) {
+        return task.split(' ')[0]
+      })
+      if (tasks.length > 0) {
+        console.info('gulp ' + tasks.join(' '))
+        runSequence(tasks, cb)
+      } else {
+        console.info('Ok, .. goodbye')
+      }
+    }))
 })
diff --git a/package.json b/package.json
index cfc70e42dbad95cbaddbcb1d9affe253356bcc0c..990c3608646c059db14c78a2b6624d998e7ecdac 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "yjs",
-  "version": "0.6.31",
+  "version": "0.6.32",
   "description": "A framework for real-time p2p shared editing on arbitrary complex data types",
   "main": "y.js",
   "scripts": {
@@ -53,6 +53,7 @@
     "gulp-jasmine-browser": "^0.2.3",
     "gulp-load-plugins": "^1.0.0",
     "gulp-prompt": "^0.1.2",
+    "gulp-rename": "^1.2.2",
     "gulp-serve": "^1.2.0",
     "gulp-shell": "^0.5.1",
     "gulp-sourcemaps": "^1.5.2",