diff --git a/local-cli/core/android/index.js b/local-cli/core/android/index.js
index cc229d298f4fd9..68d2a073c52e13 100644
--- a/local-cli/core/android/index.js
+++ b/local-cli/core/android/index.js
@@ -126,3 +126,5 @@ exports.dependencyConfig = function dependencyConfigAndroid(folder, userConfig)
 
   return { sourceDir, folder, manifest, packageImportPath, packageInstance };
 };
+
+exports.linkConfig = require('../../link/android');
diff --git a/local-cli/core/ios/index.js b/local-cli/core/ios/index.js
index 6bca5946352085..0d69ac9f11129f 100644
--- a/local-cli/core/ios/index.js
+++ b/local-cli/core/ios/index.js
@@ -57,3 +57,5 @@ exports.projectConfig = function projectConfigIOS(folder, userConfig) {
 };
 
 exports.dependencyConfig = exports.projectConfig;
+
+exports.linkConfig = require('../../link/ios');
diff --git a/local-cli/link/__tests__/link.spec.js b/local-cli/link/__tests__/link.spec.js
index b3470563d7ce40..f15fc3fee43a58 100644
--- a/local-cli/link/__tests__/link.spec.js
+++ b/local-cli/link/__tests__/link.spec.js
@@ -81,8 +81,10 @@ describe('link', () => {
   it('should register native module when android/ios projects are present', (done) => {
     const registerNativeModule = sinon.stub();
     const dependencyConfig = {android: {}, ios: {}, assets: [], commands: {}};
+    const androidLinkConfig = require('../android');
+    const iosLinkConfig = require('../ios');
     const config = {
-      getPlatformConfig: () => ({ios: {}, android: {}}),
+      getPlatformConfig: () => ({ios: { linkConfig: iosLinkConfig }, android: { linkConfig: androidLinkConfig }}),
       getProjectConfig: () => ({android: {}, ios: {}, assets: []}),
       getDependencyConfig: sinon.stub().returns(dependencyConfig),
     };
@@ -223,8 +225,9 @@ describe('link', () => {
       sinon.stub().returns(false)
     );
 
+    const linkConfig = require('../ios');
     const config = {
-      getPlatformConfig: () => ({ ios: {}}),
+      getPlatformConfig: () => ({ ios: { linkConfig: linkConfig }}),
       getProjectConfig: () => ({ ios: {}, assets: [] }),
       getDependencyConfig: sinon.stub().returns({
         ios: {}, assets: [], commands: { prelink, postlink },
@@ -251,8 +254,9 @@ describe('link', () => {
       copyAssets
     );
 
+    const linkConfig = require('../ios');
     const config = {
-      getPlatformConfig: () => ({ ios: {} }),
+      getPlatformConfig: () => ({ ios: { linkConfig: linkConfig } }),
       getProjectConfig: () => ({ ios: {}, assets: projectAssets }),
       getDependencyConfig: sinon.stub().returns(dependencyConfig),
     };
diff --git a/local-cli/link/android/copyAssets.js b/local-cli/link/android/copyAssets.js
index 0f41a301c63b9a..6b3702fa7afeec 100644
--- a/local-cli/link/android/copyAssets.js
+++ b/local-cli/link/android/copyAssets.js
@@ -17,10 +17,10 @@ const groupFilesByType = require('../groupFilesByType');
  * For now, the only types of files that are handled are:
  * - Fonts (otf, ttf) - copied to targetPath/fonts under original name
  */
-module.exports = function copyAssetsAndroid(files, targetPath) {
+module.exports = function copyAssetsAndroid(files, project) {
   const assets = groupFilesByType(files);
 
   (assets.font || []).forEach(asset =>
-    fs.copySync(asset, path.join(targetPath, 'fonts', path.basename(asset)))
+    fs.copySync(asset, path.join(project.assetsPath, 'fonts', path.basename(asset)))
   );
 };
diff --git a/local-cli/link/android/index.js b/local-cli/link/android/index.js
new file mode 100644
index 00000000000000..986ec59450b8dd
--- /dev/null
+++ b/local-cli/link/android/index.js
@@ -0,0 +1,9 @@
+module.exports = function() {
+  return {
+    isInstalled: require('./isInstalled'),
+    register: require('./registerNativeModule'),
+    unregister: require('./unregisterNativeModule'),
+    copyAssets: require('./copyAssets'),
+    unlinkAssets: require('./unlinkAssets')
+  };
+};
diff --git a/local-cli/link/android/unlinkAssets.js b/local-cli/link/android/unlinkAssets.js
index 6c8b02191ecd9e..dbaae6f7bcc9ba 100644
--- a/local-cli/link/android/unlinkAssets.js
+++ b/local-cli/link/android/unlinkAssets.js
@@ -17,11 +17,11 @@ const groupFilesByType = require('../groupFilesByType');
  * For now, the only types of files that are handled are:
  * - Fonts (otf, ttf) - copied to targetPath/fonts under original name
  */
-module.exports = function unlinkAssetsAndroid(files, targetPath) {
+module.exports = function unlinkAssetsAndroid(files, project) {
   const assets = groupFilesByType(files);
 
   (assets.font || []).forEach((file) => {
-    const filePath = path.join(targetPath, 'fonts', path.basename(file));
+    const filePath = path.join(project.assetsPath, 'fonts', path.basename(file));
     if (fs.existsSync(filePath)) {
       fs.unlinkSync(filePath);
     }
diff --git a/local-cli/link/ios/common/isInstalled.js b/local-cli/link/ios/common/isInstalled.js
new file mode 100644
index 00000000000000..a7a5f2d07d192e
--- /dev/null
+++ b/local-cli/link/ios/common/isInstalled.js
@@ -0,0 +1,6 @@
+const isInstalledIOS = require('../isInstalled');
+const isInstalledPods = require('../../pods/isInstalled');
+
+module.exports = function isInstalled(config, name) {
+  return isInstalledIOS(config, name) || isInstalledPods(config, name);
+};
diff --git a/local-cli/link/ios/common/registerNativeModule.js b/local-cli/link/ios/common/registerNativeModule.js
new file mode 100644
index 00000000000000..38ce59606982ca
--- /dev/null
+++ b/local-cli/link/ios/common/registerNativeModule.js
@@ -0,0 +1,16 @@
+const registerDependencyIOS = require('../registerNativeModule');
+const registerDependencyPods = require('../../pods/registerNativeModule');
+
+module.exports = function registerNativeModule(
+  name,
+  dependencyConfig,
+  params,
+  projectConfig
+) {
+  if (projectConfig.podfile && dependencyConfig.podspec) {
+    registerDependencyPods(name, dependencyConfig, projectConfig);
+  }
+  else {
+    registerDependencyIOS(dependencyConfig, projectConfig);
+  }
+};
diff --git a/local-cli/link/ios/common/unregisterNativeModule.js b/local-cli/link/ios/common/unregisterNativeModule.js
new file mode 100644
index 00000000000000..b42882623fbe34
--- /dev/null
+++ b/local-cli/link/ios/common/unregisterNativeModule.js
@@ -0,0 +1,22 @@
+const compact = require('lodash').compact;
+const isInstalledIOS = require('../isInstalled');
+const isInstalledPods = require('../../pods/isInstalled');
+const unregisterDependencyIOS = require('../registerNativeModule');
+const unregisterDependencyPods = require('../../pods/registerNativeModule');
+
+module.exports = function unregisterNativeModule(
+  name,
+  dependencyConfig,
+  projectConfig,
+  otherDependencies
+) {
+  const isIosInstalled = isInstalledIOS(projectConfig, dependencyConfig);
+  const isPodInstalled = isInstalledPods(projectConfig, dependencyConfig);
+  if (isIosInstalled) {
+    const iOSDependencies = compact(otherDependencies.map(d => d.config.ios));
+    unregisterDependencyIOS(dependencyConfig, projectConfig, iOSDependencies);
+  }
+  else if (isPodInstalled) {
+    unregisterDependencyPods(dependencyConfig, projectConfig);
+  }
+};
diff --git a/local-cli/link/ios/index.js b/local-cli/link/ios/index.js
new file mode 100644
index 00000000000000..9653b3be80a1d1
--- /dev/null
+++ b/local-cli/link/ios/index.js
@@ -0,0 +1,9 @@
+module.exports = function() {
+  return {
+    isInstalled: require('./common/isInstalled'),
+    register: require('./common/registerNativeModule'),
+    unregister: require('./common/unregisterNativeModule'),
+    copyAssets: require('./copyAssets'),
+    unlinkAssets: require('./unlinkAssets')
+  };
+};
diff --git a/local-cli/link/link.js b/local-cli/link/link.js
index ac0aba2a679ebd..8711f278bd08cc 100644
--- a/local-cli/link/link.js
+++ b/local-cli/link/link.js
@@ -26,14 +26,6 @@ const chalk = require('chalk');
  * run Flow. */
 const isEmpty = require('lodash').isEmpty;
 const promiseWaterfall = require('./promiseWaterfall');
-const registerDependencyAndroid = require('./android/registerNativeModule');
-const registerDependencyIOS = require('./ios/registerNativeModule');
-const registerDependencyPods = require('./pods/registerNativeModule');
-const isInstalledAndroid = require('./android/isInstalled');
-const isInstalledIOS = require('./ios/isInstalled');
-const isInstalledPods = require('./pods/isInstalled');
-const copyAssetsAndroid = require('./android/copyAssets');
-const copyAssetsIOS = require('./ios/copyAssets');
 const getProjectDependencies = require('./getProjectDependencies');
 const getDependencyConfig = require('./getDependencyConfig');
 const pollParams = require('./pollParams');
@@ -47,37 +39,8 @@ log.heading = 'rnpm-link';
 
 const dedupeAssets = (assets) => uniqBy(assets, asset => path.basename(asset));
 
-
-const linkDependencyAndroid = (androidProject, dependency) => {
-  if (!androidProject || !dependency.config.android) {
-    return null;
-  }
-
-  const isInstalled = isInstalledAndroid(androidProject, dependency.name);
-
-  if (isInstalled) {
-    log.info(chalk.grey(`Android module ${dependency.name} is already linked`));
-    return null;
-  }
-
-  return pollParams(dependency.config.params).then(params => {
-    log.info(`Linking ${dependency.name} android dependency`);
-
-    registerDependencyAndroid(
-      dependency.name,
-      dependency.config.android,
-      params,
-      androidProject
-    );
-
-    log.info(`Android module ${dependency.name} has been successfully linked`);
-  });
-};
-
-const linkDependencyPlatforms = (platforms, project, dependency) => {
-  const ignorePlatforms = ['android', 'ios'];
+const linkDependency = (platforms, project, dependency) => {
   Object.keys(platforms || {})
-    .filter(platform => ignorePlatforms.indexOf(platform) < 0)
     .forEach(platform => {
       if (!project[platform] || !dependency.config[platform]) {
         return null;
@@ -110,45 +73,12 @@ const linkDependencyPlatforms = (platforms, project, dependency) => {
     });
 };
 
-const linkDependencyIOS = (iOSProject, dependency) => {
-  if (!iOSProject || !dependency.config.ios) {
-    return;
-  }
-
-  const isInstalled = isInstalledIOS(iOSProject, dependency.config.ios) || isInstalledPods(iOSProject, dependency.config.ios);
-  if (isInstalled) {
-    log.info(chalk.grey(`iOS module ${dependency.name} is already linked`));
-    return;
-  }
-
-  log.info(`Linking ${dependency.name} ios dependency`);
-  if (iOSProject.podfile && dependency.config.ios.podspec) {
-    registerDependencyPods(dependency, iOSProject);
-  }
-  else {
-    registerDependencyIOS(dependency.config.ios, iOSProject);
-  }
-  log.info(`iOS module ${dependency.name} has been successfully linked`);
-};
-
 const linkAssets = (platforms, project, assets) => {
   if (isEmpty(assets)) {
     return;
   }
 
-  if (project.ios) {
-    log.info('Linking assets to ios project');
-    copyAssetsIOS(assets, project.ios);
-  }
-
-  if (project.android) {
-    log.info('Linking assets to android project');
-    copyAssetsAndroid(assets, project.android.assetsPath);
-  }
-
-  const ignorePlatforms = ['android', 'ios'];
   Object.keys(platforms || {})
-    .filter(platform => ignorePlatforms.indexOf(platform) < 0)
     .forEach(platform => {
       const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
       if (!linkConfig || !linkConfig.copyAssets) {
@@ -212,9 +142,7 @@ function link(args: Array<string>, config: RNConfig) {
 
   const tasks = flatten(dependencies.map(dependency => [
     () => promisify(dependency.config.commands.prelink || commandStub),
-    () => linkDependencyAndroid(project.android, dependency),
-    () => linkDependencyIOS(project.ios, dependency),
-    () => linkDependencyPlatforms(platforms, project, dependency),
+    () => linkDependency(platforms, project, dependency),
     () => promisify(dependency.config.commands.postlink || commandStub),
   ]));
 
diff --git a/local-cli/link/pods/registerNativeModule.js b/local-cli/link/pods/registerNativeModule.js
index 1032f244861228..37041cf78322c8 100644
--- a/local-cli/link/pods/registerNativeModule.js
+++ b/local-cli/link/pods/registerNativeModule.js
@@ -16,10 +16,10 @@ const findMarkedLinesInPodfile = require('./findMarkedLinesInPodfile');
 const addPodEntry = require('./addPodEntry');
 const savePodFile = require('./savePodFile');
 
-module.exports = function registerNativeModulePods(dependency, iOSProject) {
+module.exports = function registerNativeModulePods(name, dependencyConfig, iOSProject) {
   const podLines = readPodfile(iOSProject.podfile);
   const linesToAddEntry = getLinesToAddEntry(podLines, iOSProject);
-  addPodEntry(podLines, linesToAddEntry, dependency.config.ios.podspec, dependency.name);
+  addPodEntry(podLines, linesToAddEntry, dependencyConfig.podspec, name);
   savePodFile(iOSProject.podfile, podLines);
 };
 
diff --git a/local-cli/link/unlink.js b/local-cli/link/unlink.js
index 5c54526dfcc589..ed3772c4b45c39 100644
--- a/local-cli/link/unlink.js
+++ b/local-cli/link/unlink.js
@@ -10,16 +10,7 @@
 const log = require('npmlog');
 
 const getProjectDependencies = require('./getProjectDependencies');
-const unregisterDependencyAndroid = require('./android/unregisterNativeModule');
-const unregisterDependencyIOS = require('./ios/unregisterNativeModule');
-const unregisterDependencyPods = require('./pods/unregisterNativeModule');
-const isInstalledAndroid = require('./android/isInstalled');
-const isInstalledIOS = require('./ios/isInstalled');
-const isInstalledPods = require('./pods/isInstalled');
-const unlinkAssetsAndroid = require('./android/unlinkAssets');
-const unlinkAssetsIOS = require('./ios/unlinkAssets');
 const getDependencyConfig = require('./getDependencyConfig');
-const compact = require('lodash').compact;
 const difference = require('lodash').difference;
 const filter = require('lodash').filter;
 const flatten = require('lodash').flatten;
@@ -30,38 +21,17 @@ const promisify = require('./promisify');
 
 log.heading = 'rnpm-link';
 
-const unlinkDependencyAndroid = (androidProject, dependency, packageName) => {
-  if (!androidProject || !dependency.android) {
-    return;
-  }
-
-  const isInstalled = isInstalledAndroid(androidProject, packageName);
-
-  if (!isInstalled) {
-    log.info(`Android module ${packageName} is not installed`);
-    return;
-  }
-
-  log.info(`Unlinking ${packageName} android dependency`);
-
-  unregisterDependencyAndroid(packageName, dependency.android, androidProject);
+const unlinkDependency = (platforms, project, dependency, packageName, otherDependencies) => {
 
-  log.info(`Android module ${packageName} has been successfully unlinked`);
-};
-
-const unlinkDependencyPlatforms = (platforms, project, dependency, packageName) => {
-
-  const ignorePlatforms = ['android', 'ios'];
   Object.keys(platforms || {})
-    .filter(platform => ignorePlatforms.indexOf(platform) < 0)
     .forEach(platform => {
       if (!project[platform] || !dependency[platform]) {
-        return null;
+        return;
       }
 
       const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
       if (!linkConfig || !linkConfig.isInstalled || !linkConfig.unregister) {
-        return null;
+        return;
       }
 
       const isInstalled = linkConfig.isInstalled(project[platform], dependency[platform]);
@@ -76,37 +46,14 @@ const unlinkDependencyPlatforms = (platforms, project, dependency, packageName)
       linkConfig.unregister(
         packageName,
         dependency[platform],
-        project[platform]
+        project[platform],
+        otherDependencies
       );
 
       log.info(`Platform '${platform}' module ${dependency.name} has been successfully unlinked`);
     });
 };
 
-const unlinkDependencyIOS = (iOSProject, dependency, packageName, iOSDependencies) => {
-  if (!iOSProject || !dependency.ios) {
-    return;
-  }
-
-  const isIosInstalled = isInstalledIOS(iOSProject, dependency.ios);
-  const isPodInstalled = isInstalledPods(iOSProject, dependency.ios);
-  if (!isIosInstalled && !isPodInstalled) {
-    log.info(`iOS module ${packageName} is not installed`);
-    return;
-  }
-
-  log.info(`Unlinking ${packageName} ios dependency`);
-
-  if (isIosInstalled) {
-    unregisterDependencyIOS(dependency.ios, iOSProject, iOSDependencies);
-  }
-  else if (isPodInstalled) {
-    unregisterDependencyPods(dependency.ios, iOSProject);
-  }
-
-  log.info(`iOS module ${packageName} has been successfully unlinked`);
-};
-
 /**
  * Updates project and unlink specific dependency
  *
@@ -143,13 +90,10 @@ function unlink(args, config) {
 
   const allDependencies = getDependencyConfig(config, getProjectDependencies());
   const otherDependencies = filter(allDependencies, d => d.name !== packageName);
-  const iOSDependencies = compact(otherDependencies.map(d => d.config.ios));
 
   const tasks = [
     () => promisify(dependency.commands.preunlink || commandStub),
-    () => unlinkDependencyAndroid(project.android, dependency, packageName),
-    () => unlinkDependencyIOS(project.ios, dependency, packageName, iOSDependencies),
-    () => unlinkDependencyPlatforms(platforms, project, dependency, packageName),
+    () => unlinkDependency(platforms, project, dependency, packageName, otherDependencies),
     () => promisify(dependency.commands.postunlink || commandStub)
   ];
 
@@ -166,15 +110,16 @@ function unlink(args, config) {
         return Promise.resolve();
       }
 
-      if (project.ios) {
-        log.info('Unlinking assets from ios project');
-        unlinkAssetsIOS(assets, project.ios);
-      }
-
-      if (project.android) {
-        log.info('Unlinking assets from android project');
-        unlinkAssetsAndroid(assets, project.android.assetsPath);
-      }
+      Object.keys(platforms || {})
+        .forEach(platform => {
+          const linkConfig = platforms[platform] && platforms[platform].linkConfig && platforms[platform].linkConfig();
+          if (!linkConfig || !linkConfig.unlinkAssets) {
+            return;
+          }
+    
+          log.info(`Unlinking assets from ${platform} project`);
+          linkConfig.unlinkAssets(assets, project[platform]);
+        });
 
       log.info(
         `${packageName} assets has been successfully unlinked from your project`