diff --git a/app/modules/config.js b/app/modules/config.js
new file mode 100644
index 0000000000000000000000000000000000000000..40920684f47f28b45d9b406b108a1c7b44a6c87e
--- /dev/null
+++ b/app/modules/config.js
@@ -0,0 +1,12 @@
+"use strict";
+
+module.exports = {
+  duniter: {
+    cli: [{
+      name: 'config',
+      desc: 'Register configuration in database',
+      // The command does nothing particular, it just stops the process right after configuration phase is over
+      onConfiguredExecute: (server, conf, program, params, wizardTasks) => Promise.resolve(conf)
+    }]
+  }
+}
diff --git a/app/modules/gen.js b/app/modules/gen.js
new file mode 100644
index 0000000000000000000000000000000000000000..3fd46d132fa743a92b6371fbf747a0a828d10e82
--- /dev/null
+++ b/app/modules/gen.js
@@ -0,0 +1,135 @@
+"use strict";
+
+const co = require('co');
+const async = require('async');
+const multicaster = require('../lib/streams/multicaster');
+const Peer = require('../lib/entity/peer');
+const logger = require('../lib/logger')('gen');
+
+module.exports = {
+
+  duniter: {
+
+    cliOptions: [
+      {value: '--show', desc: 'With gen-next or gen-root commands, displays the generated block.'},
+      {value: '--check', desc: 'With gen-next: just check validity of generated block.'}
+    ],
+
+    cli: [{
+      name: 'gen-next [host] [port] [difficulty]',
+      desc: 'Tries to generate the next block of the blockchain.',
+      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
+        const host = params[0];
+        const port = params[1];
+        const difficulty = params[2];
+        return generateAndSend(program, host, port, difficulty, server, (server) => server.BlockchainService.generateNext);
+      })
+    }, {
+      name: 'gen-root [host] [port] [difficulty]',
+      desc: 'Tries to generate root block, with choice of root members.',
+      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
+        const host = params[0];
+        const port = params[1];
+        const difficulty = params[2];
+        if (!host) {
+          throw 'Host is required.';
+        }
+        if (!port) {
+          throw 'Port is required.';
+        }
+        if (!difficulty) {
+          throw 'Difficulty is required.';
+        }
+        return generateAndSend(program, host, port, difficulty, server, (server) => server.BlockchainService.generateManualRoot);
+      })
+    }]
+  }
+}
+
+function generateAndSend(program, host, port, difficulty, server, getGenerationMethod) {
+  return new Promise((resolve, reject) => {
+    async.waterfall([
+      function (next) {
+        const method = getGenerationMethod(server);
+        co(function*(){
+          try {
+            const block = yield method();
+            next(null, block);
+          } catch(e) {
+            next(e);
+          }
+        });
+      },
+      function (block, next) {
+        if (program.check) {
+          block.time = block.medianTime;
+          program.show && console.log(block.getRawSigned());
+          co(function*(){
+            try {
+              yield server.doCheckBlock(block);
+              logger.info('Acceptable block');
+              next();
+            } catch (e) {
+              next(e);
+            }
+          });
+        }
+        else {
+          logger.debug('Block to be sent: %s', block.quickDescription());
+          async.waterfall([
+            function (next) {
+              // Extract key pair
+              co(function*(){
+                try {
+                  const pair = yield server.conf.keyPair;
+                  next(null, pair);
+                } catch(e) {
+                  next(e);
+                }
+              });
+            },
+            function (pair, next) {
+              proveAndSend(program, server, block, pair.publicKey, parseInt(difficulty), host, parseInt(port), next);
+            }
+          ], next);
+        }
+      }
+    ], (err, data) => {
+      err && reject(err);
+      !err && resolve(data);
+    });
+  });
+}
+
+function proveAndSend(program, server, block, issuer, difficulty, host, port, done) {
+  const BlockchainService = server.BlockchainService;
+  async.waterfall([
+    function (next) {
+      block.issuer = issuer;
+      program.show && console.log(block.getRawSigned());
+      co(function*(){
+        try {
+          const proven = yield BlockchainService.prove(block, difficulty);
+          next(null, proven);
+        } catch(e) {
+          next(e);
+        }
+      });
+    },
+    function (block, next) {
+      const peer = new Peer({
+        endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
+      });
+      program.show && console.log(block.getRawSigned());
+      logger.info('Posted block ' + block.quickDescription());
+      co(function*(){
+        try {
+          yield multicaster(server.conf).sendBlock(peer, block);
+          next();
+        } catch(e) {
+          next(e);
+        }
+      });
+    }
+  ], done);
+}
diff --git a/app/modules/synchronization.js b/app/modules/synchronization.js
new file mode 100644
index 0000000000000000000000000000000000000000..87871f12ff99b188d1426387adccb20ef4bdc54a
--- /dev/null
+++ b/app/modules/synchronization.js
@@ -0,0 +1,34 @@
+"use strict";
+
+const co = require('co');
+
+module.exports = {
+  duniter: {
+    cli: [{
+      name: 'sync [host] [port] [to]',
+      desc: 'Synchronize blockchain from a remote Duniter node',
+      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
+        const host = params[0];
+        const port = params[1];
+        const to   = params[2];
+        if (!host) {
+          throw 'Host is required.';
+        }
+        if (!port) {
+          throw 'Port is required.';
+        }
+        let cautious;
+        if (program.nocautious) {
+          cautious = false;
+        }
+        if (program.cautious) {
+          cautious = true;
+        }
+        yield server.synchronize(host, port, parseInt(to), 0, !program.nointeractive, cautious, program.nopeers, program.noshuffle);
+        if (server) {
+          yield server.disconnect();
+        }
+      })
+    }]
+  }
+}
diff --git a/app/modules/wizard.js b/app/modules/wizard.js
new file mode 100644
index 0000000000000000000000000000000000000000..95fa1e0ead23aa5e5cec49f334a595d1db329578
--- /dev/null
+++ b/app/modules/wizard.js
@@ -0,0 +1,37 @@
+"use strict";
+
+const Q = require('q');
+const co = require('co');
+const wizard = require('../lib/wizard');
+const logger = require('../lib/logger')('wizard');
+
+module.exports = {
+  duniter: {
+
+    wizard: {
+      // The wizard itself also defines its personal tasks
+      'currency': Q.nbind(wizard().configCurrency, null),
+      'pow': Q.nbind(wizard().configPoW, null),
+      'network': Q.nbind(wizard().configNetwork, null),
+      'network-reconfigure': Q.nbind(wizard().configNetworkReconfigure, null),
+      'ucp': Q.nbind(wizard().configUCP, null)
+    },
+
+    cli: [{
+      name: 'wizard [step]',
+      desc: 'Launch the configuration wizard.',
+
+      onConfiguredExecute: (server, conf, program, params, wizardTasks) => co(function*() {
+        const step = params[0];
+        const tasks = step ? [wizardTasks[step]] : Object.values(wizardTasks);
+        for (const task of tasks) {
+          yield task(conf, program);
+        }
+        // Check config
+        yield server.checkConfig();
+        yield server.dal.saveConf(conf);
+        logger.debug("Configuration saved.");
+      })
+    }]
+  }
+};
diff --git a/index.js b/index.js
index 162024ba2e1d4ffd332159fba617389b2e8572e2..a5b0a15daabcab794abf5ff285dd0d879790ce37 100644
--- a/index.js
+++ b/index.js
@@ -2,218 +2,20 @@
 
 const Q = require('q');
 const co = require('co');
-const async = require('async');
 const util = require('util');
 const stream = require('stream');
 const _ = require('underscore');
-const dkeypair = require('duniter-keypair');
 const Server = require('./server');
 const directory = require('./app/lib/system/directory');
 const constants = require('./app/lib/constants');
 const wizard = require('./app/lib/wizard');
-const multicaster = require('./app/lib/streams/multicaster');
-const Peer = require('./app/lib/entity/peer');
 const logger = require('./app/lib/logger')('duniter');
 
-const configDependency = {
-  duniter: {
-    cli: [{
-      name: 'config',
-      desc: 'Register configuration in database',
-      // The command does nothing particular, it just stops the process right after configuration phase is over
-      onConfiguredExecute: (server, conf, program, params, wizardTasks) => Promise.resolve(conf)
-    }]
-  }
-};
-const wizardDependency = {
-  duniter: {
-
-    wizard: {
-      // The wizard itself also defines its personal tasks
-      'currency': Q.nbind(wizard().configCurrency, null),
-      'pow': Q.nbind(wizard().configPoW, null),
-      'network': Q.nbind(wizard().configNetwork, null),
-      'network-reconfigure': Q.nbind(wizard().configNetworkReconfigure, null),
-      'ucp': Q.nbind(wizard().configUCP, null)
-    },
-
-    cli: [{
-      name: 'wizard [step]',
-      desc: 'Launch the configuration wizard.',
-
-      onConfiguredExecute: (server, conf, program, params, wizardTasks) => co(function*() {
-        const step = params[0];
-        const tasks = step ? [wizardTasks[step]] : Object.values(wizardTasks);
-        for (const task of tasks) {
-          yield task(conf, program);
-        }
-        // Check config
-        yield server.checkConfig();
-        yield server.dal.saveConf(conf);
-        logger.debug("Configuration saved.");
-      })
-    }]
-  }
-};
-
-const syncDependency = {
-  duniter: {
-    cli: [{
-      name: 'sync [host] [port] [to]',
-      desc: 'Synchronize blockchain from a remote Duniter node',
-      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
-        const host = params[0];
-        const port = params[1];
-        const to   = params[2];
-        if (!host) {
-          throw 'Host is required.';
-        }
-        if (!port) {
-          throw 'Port is required.';
-        }
-        let cautious;
-        if (program.nocautious) {
-          cautious = false;
-        }
-        if (program.cautious) {
-          cautious = true;
-        }
-        yield server.synchronize(host, port, parseInt(to), 0, !program.nointeractive, cautious, program.nopeers, program.noshuffle);
-        if (server) {
-          yield server.disconnect();
-        }
-      })
-    }]
-  }
-};
-
-const genBlockDependency = {
-
-  duniter: {
-
-    cliOptions: [
-      {value: '--show', desc: 'With gen-next or gen-root commands, displays the generated block.'},
-      {value: '--check', desc: 'With gen-next: just check validity of generated block.'}
-    ],
-
-    cli: [{
-      name: 'gen-next [host] [port] [difficulty]',
-      desc: 'Tries to generate the next block of the blockchain.',
-      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
-        const host = params[0];
-        const port = params[1];
-        const difficulty = params[2];
-        return generateAndSend(program, host, port, difficulty, server, (server) => server.BlockchainService.generateNext);
-      })
-    }, {
-      name: 'gen-root [host] [port] [difficulty]',
-      desc: 'Tries to generate root block, with choice of root members.',
-      onPluggedDALExecute: (server, conf, program, params, startServices, stopServices) => co(function*() {
-        const host = params[0];
-        const port = params[1];
-        const difficulty = params[2];
-        if (!host) {
-          throw 'Host is required.';
-        }
-        if (!port) {
-          throw 'Port is required.';
-        }
-        if (!difficulty) {
-          throw 'Difficulty is required.';
-        }
-        return generateAndSend(program, host, port, difficulty, server, (server) => server.BlockchainService.generateManualRoot);
-      })
-    }]
-  }
-}
-
-function generateAndSend(program, host, port, difficulty, server, getGenerationMethod) {
-  return new Promise((resolve, reject) => {
-    async.waterfall([
-      function (next) {
-        const method = getGenerationMethod(server);
-        co(function*(){
-          try {
-            const block = yield method();
-            next(null, block);
-          } catch(e) {
-            next(e);
-          }
-        });
-      },
-      function (block, next) {
-        if (program.check) {
-          block.time = block.medianTime;
-          program.show && console.log(block.getRawSigned());
-          co(function*(){
-            try {
-              yield server.doCheckBlock(block);
-              logger.info('Acceptable block');
-              next();
-            } catch (e) {
-              next(e);
-            }
-          });
-        }
-        else {
-          logger.debug('Block to be sent: %s', block.quickDescription());
-          async.waterfall([
-            function (next) {
-              // Extract key pair
-              co(function*(){
-                try {
-                  const pair = yield server.conf.keyPair;
-                  next(null, pair);
-                } catch(e) {
-                  next(e);
-                }
-              });
-            },
-            function (pair, next) {
-              proveAndSend(program, server, block, pair.publicKey, parseInt(difficulty), host, parseInt(port), next);
-            }
-          ], next);
-        }
-      }
-    ], (err, data) => {
-      err && reject(err);
-      !err && resolve(data);
-    });
-  });
-}
-
-function proveAndSend(program, server, block, issuer, difficulty, host, port, done) {
-  const BlockchainService = server.BlockchainService;
-  async.waterfall([
-    function (next) {
-      block.issuer = issuer;
-      program.show && console.log(block.getRawSigned());
-      co(function*(){
-        try {
-          const proven = yield BlockchainService.prove(block, difficulty);
-          next(null, proven);
-        } catch(e) {
-          next(e);
-        }
-      });
-    },
-    function (block, next) {
-      const peer = new Peer({
-        endpoints: [['BASIC_MERKLED_API', host, port].join(' ')]
-      });
-      program.show && console.log(block.getRawSigned());
-      logger.info('Posted block ' + block.quickDescription());
-      co(function*(){
-        try {
-          yield multicaster(server.conf).sendBlock(peer, block);
-          next();
-        } catch(e) {
-          next(e);
-        }
-      });
-    }
-  ], done);
-}
+const dkeypairDependency = require('duniter-keypair');
+const configDependency = require('./app/modules/config');
+const wizardDependency = require('./app/modules/wizard');
+const genDependency = require('./app/modules/gen');
+const syncDependency = require('./app/modules/synchronization');
 
 const MINIMAL_DEPENDENCIES = [
   { name: 'duniter-config',    required: configDependency }
@@ -223,8 +25,8 @@ const DEFAULT_DEPENDENCIES = [
   { name: 'duniter-config',    required: configDependency },
   { name: 'duniter-sync',      required: syncDependency },
   { name: 'duniter-wizard',    required: wizardDependency },
-  { name: 'duniter-gen',       required: genBlockDependency },
-  { name: 'duniter-keypair',   required: dkeypair }
+  { name: 'duniter-gen',       required: genDependency },
+  { name: 'duniter-keypair',   required: dkeypairDependency }
 ];
 
 module.exports = function (home, memory, overConf) {