diff --git a/dot_config/fish/conf.d/prompt.fish b/dot_config/fish/conf.d/prompt.fish
new file mode 100644
index 0000000..50a5b5d
--- /dev/null
+++ b/dot_config/fish/conf.d/prompt.fish
@@ -0,0 +1,10 @@
+set bang_symbol \u276f
+set kube_symbol \u2388
+set kube_config "$HOME/.kube/config"
+set git_symbol  \ue0a0
+set color_git_branch brblack
+
+# git symbols and colors
+# [1] unstaged, [2] staged, [3] untracked, [4] conflicts
+set git_status \~ + ! \*
+set color_git  yellow blue red purple
diff --git a/dot_config/fish/config.fish b/dot_config/fish/config.fish
index 75ff7a2..9c6492b 100644
--- a/dot_config/fish/config.fish
+++ b/dot_config/fish/config.fish
@@ -19,6 +19,4 @@ if status is-interactive
             printf '\e[31m>>\e[39m exit \e[31m%s\e[39m\n' $ret
         end
     end
-
-    starship init fish | source
 end
diff --git a/dot_config/fish/functions/fish_prompt.add.fish b/dot_config/fish/functions/fish_prompt.add.fish
new file mode 100644
index 0000000..435d5ac
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.add.fish
@@ -0,0 +1,14 @@
+function fish_prompt.add
+    set -l text $argv[1]
+    set -l color $argv[2]
+    if test -n "$color"
+        set value (set_color $color)$text(set_color normal)
+    else
+        set value $text
+    end
+    if test -z "$prompt_string"
+        set prompt_string $value
+    else
+        set -a prompt_string $value
+    end
+end
diff --git a/dot_config/fish/functions/fish_prompt.add.pl.fish b/dot_config/fish/functions/fish_prompt.add.pl.fish
new file mode 100644
index 0000000..57a4b73
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.add.pl.fish
@@ -0,0 +1,14 @@
+function fish_prompt.add.pl
+    set -l color $argv[1]
+    set -l text $argv[2]
+    set -l sep ''
+    if test -n "$prompt_sep"
+        set sep (set_color $prev_color)$prompt_sep(set_color $color_fg)
+        set prev_color $color
+    end
+    if test -z "$prompt_string"
+        set prompt_string (set_color -b $color)(set_color $color_fg) $text
+    else
+        set -a prompt_string (set_color -b $color)$sep $text
+    end
+end
diff --git a/dot_config/fish/functions/fish_prompt.bang.fish b/dot_config/fish/functions/fish_prompt.bang.fish
new file mode 100644
index 0000000..40ca599
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.bang.fish
@@ -0,0 +1,7 @@
+function fish_prompt.bang
+    if ! string match -eq linux $TERM
+        fish_prompt.add \n$bang_symbol\  brblack
+    else
+        fish_prompt.add \n\#\  brred
+    end
+end
diff --git a/dot_config/fish/functions/fish_prompt.emoji.fish b/dot_config/fish/functions/fish_prompt.emoji.fish
new file mode 100644
index 0000000..12cd051
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.emoji.fish
@@ -0,0 +1,4 @@
+function fish_prompt.emoji
+    set emoji \U1f41f \U1f420 \U1f421
+    printf $emoji[(random 1 (count $emoji))]
+end
diff --git a/dot_config/fish/functions/fish_prompt.fish b/dot_config/fish/functions/fish_prompt.fish
new file mode 100644
index 0000000..f375667
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.fish
@@ -0,0 +1,14 @@
+function fish_prompt
+    set -g prompt_string
+    set -g prev_color
+    fish_prompt.add \[ brblack
+    fish_prompt.user
+    fish_prompt.add (prompt_pwd) blue
+    fish_prompt.kube
+    fish_prompt.git
+    fish_prompt.add \] brblack
+    fish_prompt.bang
+
+    echo $prompt_string
+    set -e prompt_string
+end
diff --git a/dot_config/fish/functions/fish_prompt.git.fish b/dot_config/fish/functions/fish_prompt.git.fish
new file mode 100644
index 0000000..257c79b
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.git.fish
@@ -0,0 +1,21 @@
+function fish_prompt.git
+    set -l is_git_tree (git rev-parse --is-inside-work-tree 2>/dev/null)
+    string match -qe 'true' "$is_git_tree" || return
+    git status --porcelain -bu | while read line
+        if string match -qr '^##' "$line"
+            set git_branch (string match -r '[^# .]+' "$line")
+            string match -qr '\[behind' $line && set git_branch "$git_branch?"
+            string match -qr '\[ahead'  $line && set git_branch "$git_branch!"
+            fish_prompt.add "$git_symbol $git_branch"
+        else
+            string match -qr "^.[MD]"    "$line" && set git_count[1] (math $git_count[1] + 1)
+            string match -qr "^[MDARC]." "$line" && set git_count[2] (math $git_count[2] + 1)
+            string match -qr "^\?\?"     "$line" && set git_count[3] (math $git_count[3] + 1)
+            string match -qr "^[ADU]{2}" "$line" && set git_count[4] (math $git_count[4] + 1)
+        end
+    end
+    test -n "$git_count[1]" && fish_prompt.add "$git_count[1]$git_status[1]" "$color_git[1]"
+    test -n "$git_count[2]" && fish_prompt.add "$git_count[2]$git_status[2]" "$color_git[2]"
+    test -n "$git_count[3]" && fish_prompt.add "$git_count[3]$git_status[3]" "$color_git[3]"
+    test -n "$git_count[4]" && fish_prompt.add "$git_count[4]$git_status[4]" "$color_git[4]"
+end
diff --git a/dot_config/fish/functions/fish_prompt.kube.fish b/dot_config/fish/functions/fish_prompt.kube.fish
new file mode 100644
index 0000000..7b0d152
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.kube.fish
@@ -0,0 +1,8 @@
+function fish_prompt.kube
+    if ! test -r "$kube_config"
+        return
+    end
+    fish_prompt.add "$kube_symbol"
+    set -l kube_context (awk -F- '($1 == "current") {print $3}' "$kube_config")
+    fish_prompt.add "$kube_context" green
+end
diff --git a/dot_config/fish/functions/fish_prompt.user.fish b/dot_config/fish/functions/fish_prompt.user.fish
new file mode 100644
index 0000000..828fda3
--- /dev/null
+++ b/dot_config/fish/functions/fish_prompt.user.fish
@@ -0,0 +1,5 @@
+function fish_prompt.user
+    if test -n "$SSH_CONNECTION" || string match -qe root "$USER"
+        fish_prompt.add $USER@$hostname brblack
+    end
+end