diff --git a/config/config.exs b/config/config.exs
index 94871922..2880dad3 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -18,14 +18,26 @@ config :shift73k, :app_global_vars,
   mailer_reply_to: "reply_to@example.com",
   mailer_from: "app_name@example.com"
 
+
 # Configures the endpoint
 config :shift73k, Shift73kWeb.Endpoint,
   url: [host: "localhost"],
-  secret_key_base: "LdIQmzV5UCWSbB2SdiWFHLgxYNObKq9Za/VyguoILxfOAMDb5IsptKCKtXTRn+Tf",
   render_errors: [view: Shift73kWeb.ErrorView, accepts: ~w(html json), layout: false],
   pubsub_server: Shift73k.PubSub,
   live_view: [signing_salt: "2D4GC4ac"]
 
+# Configures the mailer
+#
+# By default it uses the "Local" adapter which stores the emails
+# locally. You can see the emails in your browser, at "/dev/mailbox".
+#
+# For production it's recommended to configure a different adapter
+# at the `config/runtime.exs`.
+config :shift73k, Shift73k.Mailer, adapter: Swoosh.Adapters.Local
+
+# Swoosh API client is needed for adapters other than SMTP.
+config :swoosh, :api_client, false
+
 # Configures Elixir's Logger
 config :logger, :console,
   format: "$time $metadata[$level] $message\n",
diff --git a/config/runtime.exs b/config/runtime.exs
new file mode 100644
index 00000000..029407bf
--- /dev/null
+++ b/config/runtime.exs
@@ -0,0 +1,83 @@
+import Config
+
+# config/runtime.exs is executed for all environments, including
+# during releases. It is executed after compilation and before the
+# system starts, so it is typically used to load production configuration
+# and secrets from environment variables or elsewhere. Do not define
+# any compile-time configuration in here, as it won't be applied.
+# The block below contains prod specific runtime configuration.
+
+# ## Using releases
+#
+# If you use `mix release`, you need to explicitly enable the server
+# by passing the PHX_SERVER=true when you start it:
+#
+#     PHX_SERVER=true bin/shift73k start
+#
+# Alternatively, you can use `mix phx.gen.release` to generate a `bin/server`
+# script that automatically sets the env var above.
+if System.get_env("PHX_SERVER") do
+  config :shift73k, Shift73kWeb.Endpoint, server: true
+end
+
+if config_env() == :prod do
+  database_url =
+    System.get_env("DATABASE_URL") ||
+      raise """
+      environment variable DATABASE_URL is missing.
+      For example: ecto://USER:PASS@HOST/DATABASE
+      """
+
+  maybe_ipv6 = if System.get_env("ECTO_IPV6"), do: [:inet6], else: []
+
+  config :shift73k, Shift73k.Repo,
+    # ssl: true,
+    url: database_url,
+    pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10"),
+    socket_options: maybe_ipv6
+
+  # The secret key base is used to sign/encrypt cookies and other secrets.
+  # A default value is used in config/dev.exs and config/test.exs but you
+  # want to use a different value for prod and you most likely don't want
+  # to check this value into version control, so we use an environment
+  # variable instead.
+  secret_key_base =
+    System.get_env("SECRET_KEY_BASE") ||
+      raise """
+      environment variable SECRET_KEY_BASE is missing.
+      You can generate one by calling: mix phx.gen.secret
+      """
+
+  host = System.get_env("PHX_HOST") || "example.com"
+  port = String.to_integer(System.get_env("PORT") || "4000")
+
+  config :shift73k, Shift73kWeb.Endpoint,
+    url: [host: host, port: 443, scheme: "https"],
+    http: [
+      # Enable IPv6 and bind on all interfaces.
+      # Set it to  {0, 0, 0, 0, 0, 0, 0, 1} for local network only access.
+      # See the documentation on https://hexdocs.pm/plug_cowboy/Plug.Cowboy.html
+      # for details about using IPv6 vs IPv4 and loopback vs public addresses.
+      ip: {0, 0, 0, 0, 0, 0, 0, 0},
+      port: port
+    ],
+    secret_key_base: secret_key_base
+
+  # ## Configuring the mailer
+  #
+  # In production you need to configure the mailer to use a different adapter.
+  # Also, you may need to configure the Swoosh API client of your choice if you
+  # are not using SMTP. Here is an example of the configuration:
+  #
+  #     config :shift73k, Shift73k.Mailer,
+  #       adapter: Swoosh.Adapters.Mailgun,
+  #       api_key: System.get_env("MAILGUN_API_KEY"),
+  #       domain: System.get_env("MAILGUN_DOMAIN")
+  #
+  # For this example you need include a HTTP client required by Swoosh API client.
+  # Swoosh supports Hackney and Finch out of the box:
+  #
+  #     config :swoosh, :api_client, Swoosh.ApiClient.Hackney
+  #
+  # See https://hexdocs.pm/swoosh/Swoosh.html#module-installation for details.
+end
diff --git a/config/test.exs b/config/test.exs
index dd0166a9..836d7509 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -25,8 +25,8 @@ config :shift73k, Shift73kWeb.Endpoint,
 # Print only warnings and errors during test
 config :logger, level: :warn
 
-# Bamboo test mailer config
-config :shift73k, Shift73k.Mailer, adapter: Bamboo.TestAdapter
+# Swoosh test mailer config
+config :shift73k, Shift73k.Mailer, adapter: Swoosh.Adapters.Test
 
 # Import secret config
 # import_config "test.secret.exs"
diff --git a/lib/shift73k/accounts/user_notifier.ex b/lib/shift73k/accounts/user_notifier.ex
index 9c2f03f2..47b891a9 100644
--- a/lib/shift73k/accounts/user_notifier.ex
+++ b/lib/shift73k/accounts/user_notifier.ex
@@ -2,12 +2,19 @@ defmodule Shift73k.Accounts.UserNotifier do
   alias Shift73k.Mailer
   alias Shift73k.Mailer.UserEmail
 
+  def deliver(user_email, subject, body) do
+    %Swoosh.Email{} = email = UserEmail.compose(user_email, subject, body)
+    case Mailer.deliver(email) do
+      {:ok, msg} -> {:ok, msg, email}
+      err -> err
+    end
+  end
+
   @doc """
   Deliver instructions to confirm account.
   """
   def deliver_confirmation_instructions(user, url) do
-    user
-    |> UserEmail.compose("Confirm Your Account", """
+    deliver(user.email, "Confirmation instructions", """
 
     ==============================
 
@@ -21,15 +28,13 @@ defmodule Shift73k.Accounts.UserNotifier do
 
     ==============================
     """)
-    |> Mailer.deliver_later()
   end
 
   @doc """
   Deliver instructions to reset a user password.
   """
   def deliver_reset_password_instructions(user, url) do
-    user
-    |> UserEmail.compose("Reset Your Password", """
+    deliver(user.email, "Reset password instructions", """
 
     ==============================
 
@@ -43,15 +48,13 @@ defmodule Shift73k.Accounts.UserNotifier do
 
     ==============================
     """)
-    |> Mailer.deliver_later()
   end
 
   @doc """
   Deliver instructions to update a user email.
   """
   def deliver_update_email_instructions(user, url) do
-    user
-    |> UserEmail.compose("Change Your E-mail", """
+    deliver(user.email, "Update email instructions", """
 
     ==============================
 
@@ -65,6 +68,5 @@ defmodule Shift73k.Accounts.UserNotifier do
 
     ==============================
     """)
-    |> Mailer.deliver_later()
   end
 end
diff --git a/lib/shift73k/mailer.ex b/lib/shift73k/mailer.ex
index 589b722e..368ffe1d 100644
--- a/lib/shift73k/mailer.ex
+++ b/lib/shift73k/mailer.ex
@@ -1,3 +1,3 @@
 defmodule Shift73k.Mailer do
-  use Bamboo.Mailer, otp_app: :shift73k
+  use Swoosh.Mailer, otp_app: :shift73k
 end
diff --git a/lib/shift73k/mailer/user_email.ex b/lib/shift73k/mailer/user_email.ex
index d5a7bc01..c5904e8b 100644
--- a/lib/shift73k/mailer/user_email.ex
+++ b/lib/shift73k/mailer/user_email.ex
@@ -1,16 +1,16 @@
 defmodule Shift73k.Mailer.UserEmail do
-  import Bamboo.Email
+  import Swoosh.Email
 
   @mailer_vars Application.compile_env(:shift73k, :app_global_vars,
                  mailer_reply_to: "admin@example.com",
                  mailer_from: {"Shift73k", "shift73k@example.com"}
                )
 
-  def compose(user, subject, body_text) do
-    new_email()
+  def compose(user_email, subject, body_text) do
+    new()
     |> from(@mailer_vars[:mailer_from])
-    |> to(user.email)
-    |> put_header("Reply-To", @mailer_vars[:mailer_reply_to])
+    |> to(user_email)
+    |> header("Reply-To", @mailer_vars[:mailer_reply_to])
     |> subject(subject)
     |> text_body(body_text)
   end
diff --git a/lib/shift73k_web/endpoint.ex b/lib/shift73k_web/endpoint.ex
index 54596874..cf633bcf 100644
--- a/lib/shift73k_web/endpoint.ex
+++ b/lib/shift73k_web/endpoint.ex
@@ -39,11 +39,6 @@ defmodule Shift73kWeb.Endpoint do
     plug(Phoenix.Ecto.CheckRepoStatus, otp_app: :shift73k)
   end
 
-  plug(Phoenix.LiveDashboard.RequestLogger,
-    param_key: "request_logger",
-    cookie_key: "request_logger"
-  )
-
   plug(Plug.RequestId)
   plug(Plug.Telemetry, event_prefix: [:phoenix, :endpoint])
 
diff --git a/lib/shift73k_web/live/user/registration.ex b/lib/shift73k_web/live/user/registration.ex
index e9d8976a..8b86b0fe 100644
--- a/lib/shift73k_web/live/user/registration.ex
+++ b/lib/shift73k_web/live/user/registration.ex
@@ -40,7 +40,7 @@ defmodule Shift73kWeb.UserLive.Registration do
     |> Accounts.register_user()
     |> case do
       {:ok, user} ->
-        {:ok, %Bamboo.Email{}} =
+        {:ok, _, %Swoosh.Email{} = _captured_email} =
           Accounts.deliver_user_confirmation_instructions(
             user,
             &Routes.user_confirmation_url(socket, :confirm, &1)
diff --git a/lib/shift73k_web/live/user_management/form_component.ex b/lib/shift73k_web/live/user_management/form_component.ex
index 2a6f7512..aa79b622 100644
--- a/lib/shift73k_web/live/user_management/form_component.ex
+++ b/lib/shift73k_web/live/user_management/form_component.ex
@@ -33,7 +33,7 @@ defmodule Shift73kWeb.UserManagement.FormComponent do
   defp save_user(%{assigns: %{action: :new}} = socket, user_params) do
     case Accounts.register_user(user_params) do
       {:ok, user} ->
-        {:ok, %Bamboo.Email{}} =
+        {:ok, _, %Swoosh.Email{} = _captured_email} =
           Accounts.deliver_user_confirmation_instructions(
             user,
             &Routes.user_confirmation_url(socket, :confirm, &1)
diff --git a/lib/shift73k_web/router.ex b/lib/shift73k_web/router.ex
index 1cdf67b0..b45acda4 100644
--- a/lib/shift73k_web/router.ex
+++ b/lib/shift73k_web/router.ex
@@ -13,10 +13,6 @@ defmodule Shift73kWeb.Router do
     plug(:fetch_current_user)
   end
 
-  pipeline :api do
-    plug(:accepts, ["json"])
-  end
-
   pipeline :user do
     plug(EnsureRolePlug, [:admin, :manager, :user])
   end
@@ -29,33 +25,24 @@ defmodule Shift73kWeb.Router do
     plug(EnsureRolePlug, :admin)
   end
 
+  # Enables the Swoosh mailbox preview in development.
+  #
+  # Note that preview only shows emails that were sent by the same
+  # node running the Phoenix server.
+  if Mix.env() == :dev do
+    scope "/dev" do
+      pipe_through :browser
+
+      forward "/mailbox", Plug.Swoosh.MailboxPreview
+    end
+  end
+
   scope "/", Shift73kWeb do
     pipe_through([:browser])
 
     get("/", Redirector, to: "/assign")
   end
 
-  # Other scopes may use custom stacks.
-  # scope "/api", Shift73kWeb do
-  #   pipe_through :api
-  # end
-
-  # Enables LiveDashboard only for development
-  #
-  # If you want to use the LiveDashboard in production, you should put
-  # it behind authentication and allow only admins to access it.
-  # If your application does not have an admins-only section yet,
-  # you can use Plug.BasicAuth to set up some basic authentication
-  # as long as you are also using SSL (which you should anyway).
-  if Mix.env() in [:dev, :test] do
-    import Phoenix.LiveDashboard.Router
-
-    scope "/" do
-      pipe_through(:browser)
-      live_dashboard("/dashboard", metrics: Shift73kWeb.Telemetry)
-    end
-  end
-
   scope "/", Shift73kWeb do
     pipe_through([:browser, :redirect_if_user_is_authenticated])
 
diff --git a/test/support/fixtures/accounts_fixtures.ex b/test/support/fixtures/accounts_fixtures.ex
index e8b49dfe..18a8264c 100644
--- a/test/support/fixtures/accounts_fixtures.ex
+++ b/test/support/fixtures/accounts_fixtures.ex
@@ -33,11 +33,8 @@ defmodule Shift73k.AccountsFixtures do
   end
 
   def extract_user_token(fun) do
-    # {:ok, captured} = fun.(&"[TOKEN]#{&1}[TOKEN]")
-    # [_, token, _] = String.split(captured.body, "[TOKEN]")
-    # token
-    {:ok, %Bamboo.Email{} = email} = fun.(&"[TOKEN]#{&1}[TOKEN]")
-    [_, token, _] = String.split(email.text_body, "[TOKEN]")
+    {:ok, _, %Swoosh.Email{} = captured_email} = fun.(&"[TOKEN]#{&1}[TOKEN]")
+    [_, token | _] = String.split(captured_email.text_body, "[TOKEN]")
     token
   end