diff --git a/lua/lualine/components/diagnostics.lua b/lua/lualine/components/diagnostics.lua
index 5159d04..0fb444c 100644
--- a/lua/lualine/components/diagnostics.lua
+++ b/lua/lualine/components/diagnostics.lua
@@ -80,7 +80,7 @@ local function diagnostics(options)
   end
 
   local highlight_groups = {}
-  local function add_highlights()
+  if options.colored then
     highlight_groups = {
       error = highlight.create_component_highlight_group(
           {fg = options.color_error}, 'diagnostics_error', options),
@@ -91,11 +91,6 @@ local function diagnostics(options)
     }
   end
 
-  if options.colored then
-    add_highlights()
-    utils.expand_set_theme(add_highlights)
-  end
-
   return function()
     local error_count, warning_count, info_count = 0, 0, 0
     local diagnostic_data = get_diagnostics(options.sources)
diff --git a/lua/lualine/components/diff.lua b/lua/lualine/components/diff.lua
index 97ff9a1..c039e68 100644
--- a/lua/lualine/components/diff.lua
+++ b/lua/lualine/components/diff.lua
@@ -108,7 +108,7 @@ local function diff(options)
   local highlights = {}
 
   -- create highlights and save highlight_name in highlights table
-  local function create_highlights()
+  if options.colored then
     highlights = {
       added = highlight.create_component_highlight_group(
           {fg = options.color_added}, 'diff_added', options),
@@ -125,12 +125,6 @@ local function diff(options)
     autocmd lualine BufWritePost * lua require'lualine.components.diff'.update_git_diff()
     ]], false)
 
-  -- create highlights
-  if options.colored then
-    create_highlights()
-    utils.expand_set_theme(create_highlights)
-  end
-
   -- Function that runs everytime statusline is updated
   return function()
     if git_diff == nil then return '' end
diff --git a/lua/lualine/highlight.lua b/lua/lualine/highlight.lua
index 158fa6d..7f8bf42 100644
--- a/lua/lualine/highlight.lua
+++ b/lua/lualine/highlight.lua
@@ -5,7 +5,7 @@ local utils_colors = require 'lualine.utils.cterm_colors'
 local utils = require 'lualine.utils.utils'
 local section_highlight_map = {x = 'c', y = 'b', z = 'a'}
 
-local function highlight(name, foreground, background, gui)
+function M.highlight(name, foreground, background, gui, reload)
   local command = {'highlight', name}
   if foreground and foreground ~= 'none' then
     table.insert(command, 'ctermfg=' .. utils_colors.get_cterm_color(foreground))
@@ -20,14 +20,16 @@ local function highlight(name, foreground, background, gui)
     table.insert(command, 'gui=' .. gui)
   end
   vim.cmd(table.concat(command, ' '))
-  utils.save_highlight(name)
+  if not reload then
+    utils.save_highlight(name, {name, foreground, background, gui, true})
+  end
 end
 
 function M.create_highlight_groups(theme)
   for mode, sections in pairs(theme) do
     for section, colorscheme in pairs(sections) do
       local highlight_group_name = {'lualine', section, mode}
-      highlight(table.concat(highlight_group_name, '_'), colorscheme.fg,
+      M.highlight(table.concat(highlight_group_name, '_'), colorscheme.fg,
                 colorscheme.bg, colorscheme.gui)
     end
   end
@@ -72,7 +74,7 @@ function M.create_component_highlight_group(color, highlight_tag, options)
     -- each mode as they will surely look the same. So we can work without options
     local highlight_group_name = table.concat(
                                      {'lualine', highlight_tag, 'no_mode'}, '_')
-    highlight(highlight_group_name, color.fg, color.bg, color.gui)
+    M.highlight(highlight_group_name, color.fg, color.bg, color.gui)
     return highlight_group_name
   end
 
@@ -93,11 +95,11 @@ function M.create_component_highlight_group(color, highlight_tag, options)
     -- Check if it's same as normal mode if it is no need to create aditional highlight
     if mode ~= 'normal' then
       if bg ~= normal_hl.bg or fg ~= normal_hl.fg then
-        highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
+        M.highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
       end
     else
       normal_hl = {bg = bg, fg = fg}
-      highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
+      M.highlight(table.concat(highlight_group_name, '_'), fg, bg, color.gui)
     end
   end
   return options.self.section .. '_' .. highlight_tag
@@ -189,21 +191,16 @@ function M.get_transitional_highlights(left_section_data, right_section_data,
 
   if not utils.highlight_exists(highlight_name) then
     -- Create the highlight_group if needed
-    local function set_transitional_highlights()
-      -- Get colors from highlights
-      -- using string.format to convert decimal to hexadecimal
-      local fg = utils.extract_highlight_colors(left_highlight_name, 'guibg')
-      local bg = utils.extract_highlight_colors(right_highlight_name, 'guibg')
-      if not fg then fg = 'none' end
-      if not bg then bg = 'none' end
-      -- swap the bg and fg when reverse is true. As in that case highlight will
-      -- be placed before section
-      if reverse then fg, bg = bg, fg end
-      highlight(highlight_name, fg, bg)
-    end
-    -- Create highlights and setup to survive colorscheme changes
-    set_transitional_highlights()
-    utils.expand_set_theme(set_transitional_highlights)
+    -- Get colors from highlights
+    -- using string.format to convert decimal to hexadecimal
+    local fg = utils.extract_highlight_colors(left_highlight_name, 'guibg')
+    local bg = utils.extract_highlight_colors(right_highlight_name, 'guibg')
+    if not fg then fg = 'none' end
+    if not bg then bg = 'none' end
+    -- swap the bg and fg when reverse is true. As in that case highlight will
+    -- be placed before section
+    if reverse then fg, bg = bg, fg end
+    M.highlight(highlight_name, fg, bg)
   end
   return '%#' .. highlight_name .. '#'
 end
diff --git a/lua/lualine/init.lua b/lua/lualine/init.lua
index 93c5036..cec498c 100644
--- a/lua/lualine/init.lua
+++ b/lua/lualine/init.lua
@@ -1,6 +1,5 @@
 -- Copyright (c) 2020-2021 hoob3rt
 -- MIT license, see LICENSE for more details.
-local utils = require('lualine.utils.utils')
 local utils_section = require('lualine.utils.section')
 local highlight = require('lualine.highlight')
 local config = require('lualine.defaults')
@@ -69,11 +68,9 @@ local function load_special_components(component)
       -- filters g portion from g:var
       local scope = component:match('[gvtwb]?o?')
       -- filters var portion from g:var
-      -- For some reason overwriting component var from outer scope causes the
-      -- component not to work . So creating a new local name component to use:/
-      local component = component:sub(#scope + 2, #component)
+      local var_name = component:sub(#scope + 2, #component)
       -- Displays nothing when veriable aren't present
-      local return_val = vim[scope][component]
+      local return_val = vim[scope][var_name]
       if return_val == nil then return '' end
       local ok
       ok, return_val = pcall(tostring, return_val)
@@ -122,13 +119,9 @@ local function component_loader(component)
     end
     -- set custom highlights
     if component.color then
-      local function update_color()
-        component.color_highlight = highlight.create_component_highlight_group(
-                                        component.color,
-                                        component.component_name, component)
-      end
-      update_color()
-      utils.expand_set_theme(update_color)
+      component.color_highlight = highlight.create_component_highlight_group(
+                                      component.color,
+                                      component.component_name, component)
     end
   end
 end
@@ -162,27 +155,6 @@ local function load_extensions()
   end
 end
 
-local function lualine_set_theme()
-  if type(config.options.theme) == 'string' then
-    config.options.theme = require('lualine.themes.' .. config.options.theme)
-    -- change the theme table in component so their custom
-    -- highlights can reflect theme change
-    local function reset_component_theme(sections)
-      for _, section in pairs(sections) do
-        for _, component in pairs(section) do
-          if type(component) == 'table' then
-            component.theme = config.options.theme
-          end
-        end
-      end
-    end
-    reset_component_theme(config.sections)
-    reset_component_theme(config.inactive_sections)
-  end
-  utils.clear_highlights()
-  highlight.create_highlight_groups(config.options.theme)
-end
-
 local function statusline(sections, is_focused)
   local function create_status_builder()
     -- The sequence sections should maintain
@@ -296,12 +268,14 @@ end
 local function tabline() return statusline(config.tabline, true) end
 
 local function setup_theme()
-  lualine_set_theme()
-  _G.lualine_set_theme = lualine_set_theme
+  if type(config.options.theme) == 'string' then
+    config.options.theme = require('lualine.themes.' .. config.options.theme)
+  end
+  highlight.create_highlight_groups(config.options.theme)
   vim.api.nvim_exec([[
   augroup lualine
   autocmd!
-  autocmd ColorScheme * call v:lua.lualine_set_theme()
+  autocmd ColorScheme * lua require'lualine.utils.utils'.reload_highlights()
   augroup END
   ]], false)
 end
diff --git a/lua/lualine/utils/utils.lua b/lua/lualine/utils/utils.lua
index 98d6ebb..036718f 100644
--- a/lua/lualine/utils/utils.lua
+++ b/lua/lualine/utils/utils.lua
@@ -2,17 +2,6 @@
 -- MIT license, see LICENSE for more details.
 local M = {}
 
--- Works as a decorator to expand set_lualine_theme functions
--- functionality at runtime .
-function M.expand_set_theme(func)
-  -- execute a local version of global function to not get in a inf recurtion
-  local set_theme = _G.lualine_set_theme
-  _G.lualine_set_theme = function()
-    set_theme()
-    func()
-  end
-end
-
 -- Note for now only works for termguicolors scope can be background or foreground
 function M.extract_highlight_colors(color_group, scope)
   if vim.fn.hlexists(color_group) == 0 then return nil end
@@ -41,15 +30,14 @@ end
 M.loaded_highlights = {}
 
 -- sets loaded_highlights table
-function M.save_highlight(highlight_name)
-  M.loaded_highlights[highlight_name] = true
+function M.save_highlight(highlight_name, highlight_args)
+  M.loaded_highlights[highlight_name] = highlight_args
 end
 
--- clears loaded_highlights table and highlights
-function M.clear_highlights()
-  for highlight_name, _ in pairs(M.loaded_highlights) do
-    vim.cmd('highlight clear ' .. highlight_name)
-    M.loaded_highlights[highlight_name] = nil
+function M.reload_highlights()
+  local highlight = require('lualine.highlight')
+  for _, highlight_args in pairs(M.loaded_highlights) do
+     highlight.highlight(unpack(highlight_args))
   end
 end