diff --git a/init.fish b/init.fish
index 82cfc65d6c43659b1bc705b8ca2fcd4407e09a9b..026ac06a3f34669f2912a4130ad73e7d7b78701b 100644
--- a/init.fish
+++ b/init.fish
@@ -1,55 +1,42 @@
-# SYNOPSIS
-#   Initialize Oh My Fish.
-#
-# OVERVIEW
-#   + Source $OMF_CONFIG/before.init.fish
-#
-#   + Autoload Oh My Fish packages, themes and config path
-#   + For each <pkg> inside {$OMF_PATH,$OMF_CONFIG}
-#     + Autoload <pkg> directory
-#     + Source <pkg>.fish
-#     + Emit init_<pkg> event
-#
-#   + Autoload {$OMF_PATH,$OMF_CONFIG}/functions
-#   + Source $OMF_CONFIG/init.fish
-#
-# ENV
-#   OMF_PATH      ~/.local/share/omf by default.
-#   OMF_IGNORE    List of packages to ignore.
-#   OMF_CONFIG    ~/.config/omf by default.
-#   OMF_VERSION   Oh My Fish! version
-
 # Set OMF_CONFIG if not set.
 if not set -q OMF_CONFIG
   set -q XDG_CONFIG_HOME; or set -l XDG_CONFIG_HOME "$HOME/.config"
   set -gx OMF_CONFIG "$XDG_CONFIG_HOME/omf"
 end
-
 # Source custom before.init.fish file
 source $OMF_CONFIG/before.init.fish ^/dev/null
-
-# Save the head of function path and autoload core functions
-set -l user_function_path $fish_function_path[1]
-set fish_function_path[1] $OMF_PATH/lib
-
-# Autoload util functions
-autoload $OMF_PATH/lib $OMF_PATH/lib/git
-
-for path in {$OMF_PATH,$OMF_CONFIG}/pkg/*
-  set -l name (basename $path)
-
-  contains -- $name $OMF_IGNORE; and continue
-  require $name
-end
-
-# Autoload theme
-autoload {$OMF_PATH,$OMF_CONFIG}/themes/(cat $OMF_CONFIG/theme)
-
-# Autoload custom functions
-autoload $OMF_CONFIG/functions
-autoload $user_function_path
-
+# Read current theme
+read -l theme < $OMF_CONFIG/theme
+# Prepare Oh My Fish paths
+set -l omf_function_path $OMF_PATH/{lib/{,git}}
+set -l omf_package_function_path {$OMF_CONFIG,$OMF_PATH}/{themes*/$theme/{,functions},pkg/*/{,functions},functions*}
+set -l omf_package_complete_path {$OMF_CONFIG,$OMF_PATH}/{themes*/$theme/completions,pkg/*/completions}
+# Autoload functions
+set fish_function_path $fish_function_path[1] \
+                       $omf_package_function_path \
+                       $omf_function_path \
+                       $fish_function_path[2..-1]
+# Autoload completions
+set fish_complete_path $fish_complete_path[1] \
+                       $omf_package_complete_path \
+                       $fish_complete_path[2..-1]
+# Do package initialization
+initialize {$OMF_CONFIG,$OMF_PATH}/{pkg,theme}/*/init.fish
 # Source custom init.fish file
 source $OMF_CONFIG/init.fish ^/dev/null
-
-set -g OMF_VERSION "1.0.0"
+# Backup key bindings
+functions -q fish_user_key_bindings
+  and functions -c fish_user_key_bindings __original_fish_user_key_bindings
+# Override key bindings, calling original if existant
+function fish_user_key_bindings
+  # Read packages key bindings
+  for file in {$OMF_CONFIG,$OMF_PATH}/{pkg,theme}/*/key_bindings.fish
+    source $file
+  end
+  # Read custom key bindings file
+  source $OMF_CONFIG/key_bindings.fish ^/dev/null
+  # Call original key bindings if existant
+  functions -q __original_fish_user_key_bindings
+    and __original_fish_user_key_bindings
+end
+set -g OMF_VERSION "1.1.0-dev"
diff --git a/lib/initialize.fish b/lib/initialize.fish
new file mode 100644
index 0000000000000000000000000000000000000000..0e7fa3658a37369667c8326d31cc81594d6b009f
--- /dev/null
+++ b/lib/initialize.fish
@@ -0,0 +1,22 @@
+function initialize -d "Initialize a package"
+  for init in $argv
+    set -l IFS '/'
+    echo $init | read -la components
+
+    set package $components[-2]
+    set path (printf '/%s' $components[1..-2])
+    set bundle $path/bundle
+
+    if test -f $bundle
+      while read -l type dependency
+        test "$type" = package
+          and require "$dependency"
+      end < $bundle
+    end
+
+    source $init $path
+    emit init_$package $path
+
+    set -g omf_packages_loaded $omf_packages_loaded $package
+  end
+end
diff --git a/lib/require.fish b/lib/require.fish
index db7c9598a158f8ad87c257d5567863eaa30cf1b3..21a99e69012d67762d95ff7b3c502d5f2feade6c 100644
--- a/lib/require.fish
+++ b/lib/require.fish
@@ -1,41 +1,32 @@
-# SYNOPSIS
-#   require [name]
-#
-# OVERVIEW
-#   Require a plugin:
-#     - Autoload its functions and completions.
-#     - Require bundle dependencies.
-#     - Source its initialization file.
-#     - Emit its initialization event.
-#
-#   If the required plugin has already been loaded, does nothing.
+function require
+  set packages $argv
 
-function require -a name
   # Skip if plugin has already been loaded.
-  contains -- $OMF_PATH/pkg/$name $fish_function_path;
-    or contains -- $OMF_CONFIG/pkg/$name $fish_function_path;
-    and return 0
+  for package in $packages
+    if contains -- $package $omf_packages_loaded
+      set index (contains -i -- $package $packages)
+      set -e packages[$index]
+    end
+  end
 
-  for path in {$OMF_PATH,$OMF_CONFIG}/pkg/$name
-    test -d $path; or continue
+  set function_path {$OMF_PATH,$OMF_CONFIG}/pkg*/$packages{,/functions}
+  set completion_path {$OMF_PATH,$OMF_CONFIG}/pkg*/$packages/completions
 
-    if autoload $path $path/functions $path/completions
+  # Autoload functions
+  test "$function_path"
+    and set fish_function_path $fish_function_path[1] \
+                               $function_path \
+                               $fish_function_path[2..-1]
 
-      if test -f $path/bundle
-        for line in (cat $path/bundle)
-          test (echo $line | cut -d' ' -f1) = package;
-            and set dependency (basename (echo $line | cut -d' ' -f2));
-              and require $dependency
-        end
-      end
+  # Autoload completions
+  test "$complete_path"
+    and set fish_complete_path $fish_complete_path[1] \
+                               $complete_path \
+                               $fish_complete_path[2..-1]
 
-      source $path/init.fish ^/dev/null;
-        or source $path/$name.fish ^/dev/null;
-        and emit init_$name $path
-    end
-  end
+  initialize {$OMF_CONFIG,$OMF_PATH}/pkg*/$packages/init.fish
 
-  functions -e init  # Cleanup previously sourced function
+  set -g omf_packages_loaded $packages $omf_packages_loaded
 
   return 0
 end