diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..909302e
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,6 @@
+[submodule "3rd-party/z"]
+	path = 3rd-party/z
+	url = https://github.com/rupa/z.git
+[submodule "3rd-party/complete-alias"]
+	path = 3rd-party/complete-alias
+	url = https://github.com/cykerway/complete-alias.git
diff --git a/3rd-party/complete-alias b/3rd-party/complete-alias
new file mode 160000
index 0000000..7f2555c
--- /dev/null
+++ b/3rd-party/complete-alias
@@ -0,0 +1 @@
+Subproject commit 7f2555c2fe7a1f248ed2d4301e46c8eebcbbc4e2
diff --git a/_helpers.bash b/_helpers.bash
new file mode 100644
index 0000000..b3f8e8b
--- /dev/null
+++ b/_helpers.bash
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+function basedir() {
+	(cd "$(dirname \"$-2\")" && pwd)
+}
+
+function _source_file_if_exists() {
+	if [ -r "$1" ]; then
+		test -n "$DEBUG_BASHRC" && echo "-- Sourcing file $1"
+		source "$1"
+	fi
+}
+
+function _source_dir_files() {
+	if [ -d "$1" ]; then
+		test -n "$DEBUG_BASHRC" && echo "-- Sourcing files in directory $1"
+
+		# Safe loops for empty dirs
+		shopt -s nullglob
+
+		for file in "$1"/*; do
+			if [ -e "$file" ]; then
+				test -n "$DEBUG_BASHRC" && echo "    * sourcing file $file"
+				source "$file"
+			fi
+		done
+
+		# Restore option nullglob to normal
+		shopt -u nullglob
+	fi
+}
+
+# Source : https://superuser.com/questions/39751/add-directory-to-path-if-its-not-already-there
+_path_add() {
+	if [ -d "$1" ] && [[ ":$PATH:" != *":$1:"* ]]; then
+		PATH="${PATH:+"$PATH:"}$1"
+	fi
+}
+
+_prompt_command_add() {
+	if [ -n "$1" ] && [[ ":$PROMPT_COMMAND:" != *":$1:"* ]]; then
+		PROMPT_COMMAND="${PROMPT_COMMAND:+"$PROMPT_COMMAND;"}$1"
+	fi
+}
diff --git a/aliases.d/lsd b/aliases.d/lsd
index bbfe47b..e614253 100644
--- a/aliases.d/lsd
+++ b/aliases.d/lsd
@@ -2,5 +2,6 @@
 
 if (command -v lsd &> /dev/null)
 then
-  alias ls=lsd
+  alias ls='lsd'
+  alias lt='lsd --tree'
 fi
diff --git a/bashrc b/bashrc
index 89ba24c..5c90a3b 100644
--- a/bashrc
+++ b/bashrc
@@ -11,37 +11,51 @@ if [[ $- != *i* ]]; then
 	return
 fi
 
-# Safe loops for empty dirs
-shopt -s nullglob
+# DEBUG_BASHRC=true
+
+# Determine path to directory of this file (FIX: remove dependency to readlink for posix compliance)
+BASEDIR=$(
+	source_file=$(readlink -f "${BASH_SOURCE[0]}")
+	source_dir=$(dirname "${source_file}")
+	cd "${source_dir}" && pwd
+)
+
+# Source some helpers functions
+source "${BASEDIR}/_helpers.bash"
 
 # Source custom libs
-if [ -d "$HOME"/.bash/libs ]; then for lib in "$HOME"/.bash/libs/*.bash; do source "$lib"; done; fi
+_source_dir_files "${BASEDIR}"/libs
+
+# Source 3rd party libs if they exists
+_source_file_if_exists "${BASEDIR}/3rd-party/complete-alias/complete_alias"
+# _source_file_if_exists "${BASEDIR}/3rd-party/z/z.sh" # FIX: Problème de gestion de la variable PROMPT_COMMAND
 
 # Early customization
-if [ -d "$HOME"/.bash/rc.before.d ]; then for file in "$HOME"/.bash/rc.before.d/*; do source "$file"; done; fi
+_source_dir_files "${BASEDIR}"/rc.before.d
 
 # Source rc.d/*
-if [ -d "$HOME"/.bash/rc.d ]; then for file in "$HOME"/.bash/rc.d/*; do source "$file"; done; fi
+_source_dir_files "${BASEDIR}"/rc
+_source_dir_files "${BASEDIR}"/rc.d
 
 # Source alias definitions
-if [ -f "$HOME"/.bash_aliases ]; then source "$HOME"/.bash_aliases; fi
-if [ -f "$HOME"/.bash/aliases ]; then source "$HOME"/.bash/aliases; fi
-if [ -d "$HOME"/.bash/aliases ]; then for file in "$HOME"/.bash/aliases/*; do source "$file"; done; fi
-if [ -d "$HOME"/.bash/aliases.d ]; then for file in "$HOME"/.bash/aliases.d/*; do source "$file"; done; fi
+_source_file_if_exists ~/.bash_aliases
+_source_file_if_exists "${BASEDIR}"/aliases
+_source_dir_files "${BASEDIR}"/aliases
+_source_dir_files "${BASEDIR}"/aliases.d
+
+# Source bash completion definitions
+# TODO: Améliorer cette partie pour éviter les erreurs quand aucun fichier n'existe
+for file in /etc/bash*completion /etc/profile.d/bash*completion*; do source "$file"; done
+
+_source_file_if_exists ~/.bash_completion
+_source_file_if_exists "${BASEDIR}"/completion
+_source_dir_files "${BASEDIR}"/completion
+_source_dir_files "${BASEDIR}"/completion.d
+_source_dir_files ~/.nix-profile/share/bash-completion/completions
+
 if (command -v _complete_alias &>/dev/null); then
 	for alias in $(alias -p | awk '{print $2}' | awk -F= '{print $1}'); do complete -o default -F _complete_alias "$alias"; done
 fi
 
-# Source bash completion definitions
-for file in /etc/bash*completion /etc/profile.d/bash*completion*; do source "$file"; done
-
-if [ -f "$HOME"/.bash_completion ]; then source "$HOME"/.bash_completion; fi
-if [ -f "$HOME"/.bash/completion ]; then source "$HOME"/.bash/completion; fi
-if [ -d "$HOME"/.bash/completion ]; then for file in "$HOME"/.bash/completion/*; do source "$file"; done; fi
-if [ -d "$HOME"/.bash/completion.d ]; then for file in "$HOME"/.bash/completion.d/*; do source "$file"; done; fi
-
 # Late customization
-if [ -d "$HOME"/.bash/rc.after.d ]; then for file in "$HOME"/.bash/rc.after.d/*; do source "$file"; done; fi
-
-# Restore option nullglob to normal
-shopt -u nullglob
+_source_dir_files "${BASEDIR}"/rc.after.d
diff --git a/completion.d/chezmoi b/completion.d/chezmoi
new file mode 100644
index 0000000..acfd0bc
--- /dev/null
+++ b/completion.d/chezmoi
@@ -0,0 +1,5 @@
+#!/bin/bash
+
+if (command -v chezmoi &>/dev/null); then
+	source <(chezmoi completion bash)
+fi
diff --git a/completion.d/mise b/completion.d/mise
index f37224b..a51c4fa 100644
--- a/completion.d/mise
+++ b/completion.d/mise
@@ -1,5 +1,5 @@
 #!/bin/bash
 
 if (command -v mise &>/dev/null); then
-	source <(mise completion bash)
+	source <(mise completion bash --include-bash-completion-lib)
 fi
diff --git a/libs/basedir.bash b/libs.deprecated/basedir.bash
similarity index 100%
rename from libs/basedir.bash
rename to libs.deprecated/basedir.bash
diff --git a/libs/path.bash b/libs.deprecated/path.bash
similarity index 100%
rename from libs/path.bash
rename to libs.deprecated/path.bash
diff --git a/libs/prompt_command.bash b/libs.deprecated/prompt_command.bash
similarity index 100%
rename from libs/prompt_command.bash
rename to libs.deprecated/prompt_command.bash
diff --git a/rc.after.d/.keep b/rc.after.d/.keep
new file mode 100644
index 0000000..e69de29
diff --git a/rc.before.d/.keep b/rc.before.d/.keep
new file mode 100644
index 0000000..e69de29