diff --git a/README.md b/README.md
index e5b3f0c..45f16bb 100644
--- a/README.md
+++ b/README.md
@@ -136,6 +136,8 @@ A security audit was performed by [SAFE-Erlang-Elixir](https://github.com/SAFE-E
 
 **Please note that the minimum supported Erlang OTP version is OTP26.**
 
+<!-- tabs-open -->
+
 ### Erlang
 
 **directly**
@@ -200,8 +202,20 @@ Supervisor.init(
 )
 ```
 
+**using [`igniter`](https://hex.pm/packages/igniter)**
+
+```bash
+mix oidcc.gen.provider_configuration_worker \
+  --name MyApp.OidccConfigProvider \
+  --issuer https://accounts.google.com
+```
+
+<!-- tabs-close -->
+
 ## Usage
 
+<!-- tabs-open -->
+
 ### Companion libraries
 
 `oidcc` offers integrations for various libraries:
@@ -213,8 +227,6 @@ Supervisor.init(
 - [`oidcc_plug`](https://hex.pm/packages/oidcc_plug) - Integrations for
   [`plug`](https://hex.pm/packages/plug) and
   [`phoenix`](https://hex.pm/packages/phoenix)
-- [`phx_gen_oidcc`](https://hex.pm/packages/phx_gen_oidcc) - Setup Generator for
-  [`phoenix`](https://hex.pm/packages/phoenix)
 - [`ueberauth_oidcc`](https://hex.pm/packages/ueberauth_oidcc) - Integration for
   [`ueberauth`](https://hex.pm/packages/ueberauth)
 
@@ -332,3 +344,5 @@ for more details, see https://hexdocs.pm/oidcc/oidcc.html
 ```
 
 for more details, see https://hexdocs.pm/oidcc/Oidcc.html
+
+<!-- tabs-close -->
diff --git a/lib/mix/tasks/oidcc.gen.provider_configuration_worker.ex b/lib/mix/tasks/oidcc.gen.provider_configuration_worker.ex
new file mode 100644
index 0000000..b277da1
--- /dev/null
+++ b/lib/mix/tasks/oidcc.gen.provider_configuration_worker.ex
@@ -0,0 +1,145 @@
+defmodule Mix.Tasks.Oidcc.Gen.ProviderConfigurationWorker do
+  @example """
+  mix oidcc.gen.provider_configuration_worker \\
+    --name MyApp.OpenIDProvider \\
+    --issuer https://accounts.google.com \
+  """
+
+  @shortdoc "Generate an OpenID Connect provider configuration worker"
+  if !Code.ensure_loaded?(Igniter) do
+    @shortdoc "#{@shortdoc} | Install `igniter` to use"
+  end
+
+  @moduledoc """
+  #{@shortdoc}
+
+  Adds an `Oidcc.ProviderConfiguration.Worker` to your application and
+  configures it via the `runtime.exs` configuration file.
+
+  ## Example
+
+  ```bash
+  #{@example}
+  ```
+
+  ## Options
+
+  * `--name` or `-n` - The name of the provider configuration worker
+  * `--issuer` or `-i` - The issuer of the provider
+  """
+
+  if Code.ensure_loaded?(Igniter) do
+    use Igniter.Mix.Task
+
+    alias Igniter.Code.Module
+    alias Igniter.Project.Application
+    alias Igniter.Project.Config
+
+    @impl Igniter.Mix.Task
+    def info(_argv, _composing_task) do
+      %Igniter.Mix.Task.Info{
+        # dependencies to add
+        adds_deps: [],
+        # dependencies to add and call their associated installers, if they exist
+        installs: [],
+        # An example invocation
+        example: @example,
+        # Accept additional arguments that are not in your schema
+        # Does not guarantee that, when composed, the only options you get are the ones you define
+        extra_args?: false,
+        # A list of environments that this should be installed in, only relevant if this is an installer.
+        only: nil,
+        # a list of positional arguments, i.e `[:file]`
+        positional: [],
+        # Other tasks your task composes using `Igniter.compose_task`, passing in the CLI argv
+        # This ensures your option schema includes options from nested tasks
+        composes: [],
+        # `OptionParser` schema
+        schema: [name: :string, issuer: :string],
+        # CLI aliases
+        aliases: [n: :name, i: :issuer]
+      }
+    end
+
+    @impl Igniter.Mix.Task
+    def igniter(igniter, argv) do
+      # extract positional arguments according to `positional` above
+      {_arguments, argv} = positional_args!(argv)
+      # extract options according to `schema` and `aliases` above
+      options = setup_options(argv, igniter)
+
+      igniter
+      |> configure_issuer(options)
+      |> add_application_worker(options)
+    end
+
+    defp setup_options(argv, igniter) do
+      argv
+      |> options!()
+      |> Keyword.update(
+        :name,
+        Module.module_name(igniter, "OpenIDProvider"),
+        &Module.parse/1
+      )
+      |> Keyword.put(:app_name, Igniter.Project.Application.app_name(igniter))
+    end
+
+    defp configure_issuer(igniter, options) do
+      env_prefix =
+        options[:name] |> Macro.underscore() |> String.upcase() |> String.replace("/", "_")
+
+      config =
+        case Keyword.fetch(options, :issuer) do
+          {:ok, issuer} ->
+            quote do
+              [issuer: System.get_env(unquote("#{env_prefix}_ISSUER"), unquote(issuer))]
+            end
+
+          :error ->
+            quote do
+              [issuer: System.fetch_env!(unquote("#{env_prefix}_ISSUER"))]
+            end
+        end
+
+      Config.configure_new(
+        igniter,
+        "runtime.exs",
+        options[:app_name],
+        [options[:name]],
+        {:code, config}
+      )
+    end
+
+    defp add_application_worker(igniter, options) do
+      Application.add_new_child(
+        igniter,
+        {Oidcc.ProviderConfiguration.Worker,
+         {:code,
+          quote do
+            %{
+              name: unquote(options[:name]),
+              issuer:
+                Application.fetch_env!(unquote(options[:app_name]), unquote(options[:name]))[
+                  :issuer
+                ]
+            }
+          end}}
+      )
+    end
+  else
+    use Mix.Task
+
+    @impl Mix.Task
+    def run(_argv) do
+      Mix.shell().error("""
+      The task 'oidcc.gen.provider_configuration_worker' requires igniter to be run.
+
+      Please install igniter and try again.
+
+      For more information, see: https://hexdocs.pm/igniter
+      """)
+
+      exit({:shutdown, 1})
+    end
+  end
+end
diff --git a/mix.exs b/mix.exs
index 59224f3..3fdebf4 100644
--- a/mix.exs
+++ b/mix.exs
@@ -40,7 +40,8 @@ defmodule Oidcc.Mixfile do
       {:mock, "~> 0.3.8", only: :test},
       {:ex_doc, "~> 0.29", only: :dev, runtime: false},
       {:credo, "~> 1.7", only: :dev, runtime: false},
-      {:dialyxir, "~> 1.4", only: :dev, runtime: false}
+      {:dialyxir, "~> 1.4", only: :dev, runtime: false},
+      {:igniter, "~> 0.3.34", optional: true}
     ]
   end
 
@@ -74,7 +75,7 @@ defmodule Oidcc.Mixfile do
       source_ref: ref,
       main: "readme",
       extras: ["README.md"],
-      groups_for_modules: [Erlang: [~r/oidcc/], "Elixir": [~r/Oidcc/]],
+      groups_for_modules: [Erlang: [~r/oidcc/], "Elixir": [~r/^Oidcc/]],
       logo: "assets/logo.svg",
       assets: %{"assets" => "assets"}
     ]
diff --git a/test/mix/tasks/oidcc.gen.provider_configuration_worker_test.exs b/test/mix/tasks/oidcc.gen.provider_configuration_worker_test.exs
new file mode 100644
index 0000000..0dac8a7
--- /dev/null
+++ b/test/mix/tasks/oidcc.gen.provider_configuration_worker_test.exs
@@ -0,0 +1,94 @@
+defmodule Mix.Tasks.Oidcc.Gen.ProviderConfigurationWorkerTest do
+  use ExUnit.Case, async: true
+  import Igniter.Test
+
+  test "adds configuration if the file doesn't exist yet" do
+    test_project()
+    |> Igniter.compose_task("oidcc.gen.provider_configuration_worker", [
+      "--name",
+      "Test.Provider",
+      "--issuer",
+      "https://accounts.google.com"
+    ])
+    |> assert_creates("config/runtime.exs", """
+    import Config
+
+    config :test, Test.Provider,
+      issuer: System.get_env("TEST_PROVIDER_ISSUER", "https://accounts.google.com")
+    """)
+  end
+
+  test "patches configuration if the file exists" do
+    test_project(
+      files: %{
+        "config/runtime.exs" => """
+        import Config
+
+        config :logger, level: :info
+        """
+      }
+    )
+    |> Igniter.compose_task("oidcc.gen.provider_configuration_worker", [])
+    |> assert_has_patch("config/runtime.exs", """
+    1 1   |import Config
+    2 2   |
+      3 + |config :test, Test.OpenIDProvider, issuer: System.fetch_env!("TEST_OPEN_ID_PROVIDER_ISSUER")
+    3 4   |config :logger, level: :info
+    4 5   |
+    """)
+  end
+
+  test "adds worker to application supervision tree" do
+    test_project()
+    |> Igniter.compose_task("oidcc.gen.provider_configuration_worker", ["--name", "Test.Provider"])
+    |> assert_creates("lib/test/application.ex", """
+    defmodule Test.Application do
+      @moduledoc false
+
+      use Application
+
+      @impl true
+      def start(_type, _args) do
+        children = [
+          {Oidcc.ProviderConfiguration.Worker,
+           %{name: Test.Provider, issuer: Application.fetch_env!(:test, Test.Provider)[:issuer]}}
+        ]
+
+        opts = [strategy: :one_for_one, name: Test.Supervisor]
+        Supervisor.start_link(children, opts)
+      end
+    end
+    """)
+  end
+
+  test "keeps existing worker in application supervision tree" do
+    test_project(
+      files: %{
+        "config/runtime.exs" => """
+        import Config
+        config :test, Test.Provider, issuer: System.fetch_env!("TEST_PROVIDER_ISSUER")
+        """,
+        "lib/test/application.ex" => """
+        defmodule Test.Application do
+          @moduledoc false
+
+          use Application
+
+          @impl true
+          def start(_type, _args) do
+            children = [
+              {Oidcc.ProviderConfiguration.Worker,
+               %{name: Test.Provider, issuer: Application.fetch_env!(:test, Test.Provider)[:issuer]}}
+            ]
+
+            opts = [strategy: :one_for_one, name: Test.Supervisor]
+            Supervisor.start_link(children, opts)
+          end
+        end
+        """
+      }
+    )
+    |> Igniter.compose_task("oidcc.gen.provider_configuration_worker", ["--name", "Test.Provider"])
+    |> assert_unchanged(["config/runtime.exs", "lib/test/application.ex"])
+  end
+end