diff --git a/lib/utils/init-starter.js b/lib/utils/init-starter.js
new file mode 100644
index 0000000000000..8e383a8ce862b
--- /dev/null
+++ b/lib/utils/init-starter.js
@@ -0,0 +1,139 @@
+'use strict';
+var exec = require('child_process').exec;
+var fs = require('fs');
+var mkdirp = require('mkdirp');
+var sysPath = require('path');
+var rimraf = require('rimraf');
+var ncp = require('ncp');
+
+var logger = console;
+var commandName = 'init-starter';
+
+// Shortcut for backwards-compat fs.exists.
+var fsexists = fs.exists || sysPath.exists;
+
+// Executes `npm install` and `bower install` in rootPath.
+//
+// rootPath - String. Path to directory in which command will be executed.
+// callback - Function. Takes stderr and stdout of executed process.
+//
+// Returns nothing.
+var install = function(rootPath, callback) {
+  var prevDir = process.cwd();
+  logger.log('Installing packages...');
+  process.chdir(rootPath);
+  fsexists('bower.json', function(exists) {
+    var installCmd = 'npm install';
+    if (exists) installCmd += ' & bower install';
+    exec(installCmd, function(error, stdout, stderr) {
+      var log;
+      process.chdir(prevDir);
+      if (stdout) console.log(stdout.toString());
+      if (error != null) {
+        log = stderr.toString();
+        var bowerNotFound = /bower\: command not found/.test(log);
+        var msg = bowerNotFound ? 'You need to install Bower and then install starter dependencies: `npm install -g bower && bower install`. Error text: ' + log : log;
+        return callback(new Error(msg));
+      }
+      callback(null, stdout);
+    });
+  });
+};
+
+var ignored = function(path) {
+  return !(/^\.(git|hg)$/.test(sysPath.basename(path)));
+};
+
+// Copy starter from file system.
+//
+// starterPath   - String, file system path from which files will be taken.
+// rootPath     - String, directory to which starter files will be copied.
+// callback     - Function.
+//
+// Returns nothing.
+var copy = function(starterPath, rootPath, callback) {
+  var copyDirectory = function() {
+    ncp(starterPath, rootPath, {filter: ignored, stopOnErr: true}, function(error) {
+      if (error != null) return callback(new Error(error));
+      logger.log('Created starter directory layout');
+      install(rootPath, callback);
+    });
+  };
+
+  // Chmod with 755.
+  mkdirp(rootPath, 0x1ed, function(error) {
+    if (error != null) return callback(new Error(error));
+    fsexists(starterPath, function(exists) {
+      if (!exists) {
+        var error = "starter '" + starterPath + "' doesn't exist";
+        return callback(new Error(error));
+      }
+      logger.log('Copying local starter to "' + rootPath + '"...');
+
+      copyDirectory();
+    });
+  });
+};
+
+// Clones starter from URI.
+//
+// address     - String, URI. https:, github: or git: may be used.
+// rootPath    - String, directory to which starter files will be copied.
+// callback    - Function.
+//
+// Returns nothing.
+var clone = function(address, rootPath, callback) {
+  var gitHubRe = /(gh|github)\:(?:\/\/)?/;
+  var url = gitHubRe.test(address) ?
+    ("git://github.com/" + address.replace(gitHubRe, '') + ".git") : address;
+  logger.log('Cloning git repo "' + url + '" to "' + rootPath + '"...');
+  var cmd = 'git clone ' + url + ' "' + rootPath + '"';
+  exec(cmd, function(error, stdout, stderr) {
+    if (error != null) {
+      return callback(new Error("Git clone error: " + stderr.toString()));
+    }
+    logger.log('Created starter directory layout');
+    rimraf(sysPath.join(rootPath, '.git'), function(error) {
+      if (error != null) return callback(new Error(error));
+      install(rootPath, callback);
+    });
+  });
+};
+
+// Main function that clones or copies the starter.
+//
+// starter    - String, file system path or URI of starter.
+// rootPath    - String, directory to which starter files will be copied.
+// callback    - Function.
+//
+// Returns nothing.
+var initStarter = function(starter, options, callback) {
+  var cwd = process.cwd();
+
+  if (typeof options === 'function') {
+    callback = options;
+    options = null;
+  }
+
+  if (options === null) options = {};
+  var rootPath = options.rootPath || cwd;
+  if (options.commandName) commandName = options.commandName;
+  if (options.logger) logger = options.logger;
+
+  if (starter === '.' && rootPath === cwd) starter = null;
+  if (callback === null) callback = function(error) {
+    if (error !== null) return logger.error(error.toString());
+  };
+
+  var uriRe = /(?:https?|git(hub)?|gh)(?::\/\/|@)?/;
+  fsexists(sysPath.join(rootPath, 'package.json'), function(exists) {
+    if (exists) {
+      return callback(new Error("Directory '" + rootPath + "' is already an npm project"));
+    }
+    var isGitUri = starter && uriRe.test(starter);
+    var get = isGitUri ? clone : copy;
+    get(starter, rootPath, callback);
+  });
+};
+
+module.exports = initStarter;