diff --git a/app/lib/common-libs/programOptions.ts b/app/lib/common-libs/programOptions.ts
index ac6a4ae902938af47b1762ab6fba0b913dfa1378..2c1949959de9a52e76d1bff3acf029847ef9f0f9 100644
--- a/app/lib/common-libs/programOptions.ts
+++ b/app/lib/common-libs/programOptions.ts
@@ -24,6 +24,9 @@ export interface ProgramOptions {
   isSync: boolean
   noSources: boolean
   slow?: boolean
+  loglevel?: string
+  sqlTraces?: boolean
+  memory?: boolean
 }
 
 export const cliprogram: ProgramOptions = {
diff --git a/app/modules/DuniterModule.ts b/app/modules/DuniterModule.ts
new file mode 100644
index 0000000000000000000000000000000000000000..45f4de7d8471a0b5072ef5b56288de7e088bc641
--- /dev/null
+++ b/app/modules/DuniterModule.ts
@@ -0,0 +1,53 @@
+import {Server} from "../../server"
+import {ConfDTO} from "../lib/dto/ConfDTO"
+import {ProgramOptions} from "../lib/common-libs/programOptions"
+import {ConfDAL} from "../lib/dal/fileDALs/ConfDAL"
+import {ReadableDuniterService, Stack, TransformableDuniterService} from "../../index"
+
+export interface DuniterModule {
+  name: string
+  required: {
+    duniter: DuniterDependency
+  }
+}
+
+export interface DuniterDependency {
+  cliOptions?: CliOption[]
+  cli?: CliCommand[]
+  config?: {
+    onLoading: (conf: ConfDTO, program: ProgramOptions, logger:any, confDAL: ConfDAL) => void
+    beforeSave: (conf: ConfDTO, program: ProgramOptions, logger:any, confDAL: ConfDAL) => void
+  }
+  onReset?: {
+    data: (conf: ConfDTO, program: ProgramOptions, logger:any, confDAL: ConfDAL) => void
+    config: (conf: ConfDTO, program: ProgramOptions, logger:any, confDAL: ConfDAL) => void
+  }
+  wizard?: {
+    [k: string]: (conf: ConfDTO, program: ProgramOptions) => Promise<void>
+  }
+  service?: {
+    input: (server: Server, conf: ConfDTO, logger:any) => ReadableDuniterService
+    process: (server: Server, conf: ConfDTO, logger:any) => TransformableDuniterService
+    output: (server: Server, conf: ConfDTO, logger:any) => TransformableDuniterService
+    neutral: (server: Server, conf: ConfDTO, logger:any) => TransformableDuniterService
+  }
+}
+
+export interface CliOption {
+  value: string
+  desc: string
+  parser?: (parameter: string) => any
+}
+
+export interface CliCommand {
+  name: string
+  desc: string
+  logs?: boolean
+  preventIfRunning?: boolean
+  onConfiguredExecute?: (server: Server, conf?: ConfDTO, program?: ProgramOptions, params?: string[], wizardTasks?: any, stack?: Stack) => Promise<void>
+  onDatabaseExecute?: (server: Server, conf?: ConfDTO, program?: ProgramOptions, params?: string[],
+                       startServices?: () => Promise<void>,
+                       stopServices?: () => Promise<void>,
+                       stack?: Stack
+  ) => Promise<void>
+}
diff --git a/index.ts b/index.ts
index f36c18a77e278f4b344e06a394c437f43c089371..1f9e45ca6dbf38afde4d167b04e14480bb0ae2f1 100644
--- a/index.ts
+++ b/index.ts
@@ -26,6 +26,8 @@ import {RouterDependency} from "./app/modules/router"
 import {OtherConstants} from "./app/lib/other_constants"
 import {Directory} from "./app/lib/system/directory"
 import {Underscore} from "./app/lib/common-libs/underscore"
+import {CliCommand, DuniterDependency, DuniterModule} from "./app/modules/DuniterModule"
+import {ProgramOptions} from "./app/lib/common-libs/programOptions"
 
 const path = require('path');
 const constants = require('./app/lib/constants');
@@ -179,7 +181,7 @@ export interface DuniterService {
 export interface ReadableDuniterService extends DuniterService, stream.Readable {}
 export interface TransformableDuniterService extends DuniterService, stream.Transform {}
 
-class Stack {
+export class Stack {
 
   private injectedServices = false
 
@@ -192,7 +194,7 @@ class Stack {
   private PROCESS:any
   private loaded:any
   private wizardTasks:any
-  private definitions:any[] = []
+  private definitions:DuniterDependency[] = []
   private streams: {
     input: ReadableDuniterService[]
     process: TransformableDuniterService[]
@@ -205,7 +207,7 @@ class Stack {
     neutral: []
   }
 
-  constructor(private dependencies:any[]) {
+  constructor(private dependencies:DuniterModule[]) {
     this.cli = ExecuteCommand()
     this.configLoadingCallbacks = []
     this.configBeforeSaveCallbacks = []
@@ -227,7 +229,7 @@ class Stack {
     return this.loaded[name]
   }
 
-  registerDependency(requiredObject:any, name:string) {
+  registerDependency(requiredObject:{ duniter: DuniterDependency }, name:string) {
     if (name && this.loaded[name]) {
       // Do not try to load it twice
       return;
@@ -286,8 +288,8 @@ class Stack {
   };
 
   async processCommand (...args:any[]) {
-    const command = args[0];
-    const program = args[1];
+    const command: CliCommand = args[0];
+    const program: ProgramOptions = args[1];
     const params  = args.slice(2);
     params.pop(); // Don't need the command argument
 
@@ -393,6 +395,8 @@ class Stack {
         if (!command.onDatabaseExecute) {
           return res
         }
+      } else if (!command.onDatabaseExecute) {
+        throw `Command ${command.name} does not implement onConfiguredExecute nor onDatabaseExecute.`
       }
       // Second possible class of commands: post-service
       await server.initDAL(conf);
@@ -602,3 +606,11 @@ class ProcessStream extends stream.Transform {
     done && done();
   };
 }
+
+export const Duniter = {
+
+  run(modules: DuniterModule[] = [], args?: string[]) {
+    return Stacks.autoStack(modules).executeStack(args || process.argv)
+  }
+}
+