diff --git a/README.md b/README.md
index 3b959906..e5304fb5 100644
--- a/README.md
+++ b/README.md
@@ -23,7 +23,9 @@
   * [Using Tailwind plugins](#using-tailwind-plugins)
   * [Using with PostCSS](#using-with-postcss)
   * [Custom inputs or outputs](#custom-inputs-or-outputs)
+- [Rails Engines support](#rails-engines-support)
 - [Troubleshooting](#troubleshooting)
+  * [The `watch` command is hanging](#the-watch-command-is-hanging)
   * [Lost keystrokes or hanging when using terminal-based debugging tools (e.g. IRB, Pry, `ruby/debug`...etc.) with the Puma plugin](#lost-keystrokes-or-hanging-when-using-terminal-based-debugging-tools-eg-irb-pry-rubydebugetc-with-the-puma-plugin)
   * [Running in a docker container exits prematurely](#running-in-a-docker-container-exits-prematurely)
   * [Conflict with sassc-rails](#conflict-with-sassc-rails)
@@ -406,6 +408,14 @@ If you have Rails Engines in your application that use Tailwind CSS, they will b
 
 - The engine must have `tailwindcss-rails` as gem dependency.
 - The engine must have a `app/assets/tailwind/<engine_name>/application.css` file or your application must have overridden file in the same location of your application root.
+- The engine must register itself in Tailwindcss Rails:
+```ruby
+  initializer 'your_engine.tailwindcss' do |app|
+    ActiveSupport.on_load(:tailwindcss_rails) do
+      config.tailwindcss_rails.engines << Your::Engine.engine_name
+    end
+  end
+```
 
 ## Troubleshooting
 
diff --git a/lib/tailwindcss/commands.rb b/lib/tailwindcss/commands.rb
index b31e581b..87925b3a 100644
--- a/lib/tailwindcss/commands.rb
+++ b/lib/tailwindcss/commands.rb
@@ -3,13 +3,24 @@
 module Tailwindcss
   module Commands
     class << self
-      def compile_command(debug: false, **kwargs)
+      def rails_root
+        defined?(Rails) ? Rails.root : Pathname.new(Dir.pwd)
+      end
+
+      def remove_tempfile!
+        return unless class_variable_defined?(:@@tempfile) && @@tempfile
+
+        @@tempfile.close unless @@tempfile.closed?
+        @@tempfile.unlink if File.exist?(@@tempfile.path)
+        remove_class_variable(:@@tempfile)
+      end
+
+      def compile_command(input: application_css, debug: false, **kwargs)
         debug = ENV["TAILWINDCSS_DEBUG"].present? if ENV.key?("TAILWINDCSS_DEBUG")
-        rails_root = defined?(Rails) ? Rails.root : Pathname.new(Dir.pwd)
 
         command = [
           Tailwindcss::Ruby.executable(**kwargs),
-          "-i", rails_root.join("app/assets/tailwind/application.css").to_s,
+          "-i", input.to_s,
           "-o", rails_root.join("app/assets/builds/tailwind.css").to_s,
         ]
 
@@ -21,6 +32,22 @@ def compile_command(debug: false, **kwargs)
         command
       end
 
+      def application_css
+        return rails_root.join("app/assets/tailwind/application.css").to_s if engines_roots.empty?
+
+        @@tempfile = Tempfile.new("tailwind.application.css")
+
+        # Write content to tempfile
+        engines_roots.each do |root|
+          @@tempfile.write("@import \"#{root}\";\n")
+        end
+        @@tempfile.write("\n@import \"#{rails_root.join('app/assets/tailwind/application.css')}\";\n")
+        @@tempfile.flush
+        @@tempfile.close
+
+        @@tempfile.path
+      end
+
       def watch_command(always: false, poll: false, **kwargs)
         compile_command(**kwargs).tap do |command|
           command << "-w"
@@ -39,39 +66,19 @@ def rails_css_compressor?
         defined?(Rails) && Rails&.application&.config&.assets&.css_compressor.present?
       end
 
-      def engines_tailwindcss_roots
+      def engines_roots
         return [] unless defined?(Rails)
+        return [] unless Rails.application&.config&.tailwindcss_rails&.engines
 
-        Rails::Engine.subclasses.select do |engine|
-          begin
-            spec = Gem::Specification.find_by_name(engine.engine_name)
-            spec.dependencies.any? { |d| d.name == 'tailwindcss-rails' }
-          rescue Gem::MissingSpecError
-            false
-          end
+        Rails::Engine.descendants.select do |engine|
+          engine.engine_name.in?(Rails.application.config.tailwindcss_rails.engines)
         end.map do |engine|
           [
-            Rails.root.join("app/assets/tailwind/#{engine.engine_name}/application.css"),
+            rails_root.join("app/assets/tailwind/#{engine.engine_name}/application.css"),
             engine.root.join("app/assets/tailwind/#{engine.engine_name}/application.css")
           ].select(&:exist?).compact.first.to_s
         end.compact
       end
-
-      def enhance_command(command)
-        engine_roots = Tailwindcss::Commands.engines_tailwindcss_roots
-        if engine_roots.any?
-          Tempfile.create('tailwind.css') do |file|
-            file.write(engine_roots.map { |root| "@import \"#{root}\";" }.join("\n"))
-            file.write("\n@import \"#{Rails.root.join('app/assets/tailwind/application.css')}\";\n")
-            file.rewind
-            transformed_command = command.dup
-            transformed_command[2] = file.path
-            yield transformed_command if block_given?
-          end
-        else
-          yield command if block_given?
-        end
-      end
     end
   end
 end
diff --git a/lib/tailwindcss/engine.rb b/lib/tailwindcss/engine.rb
index 7b88c5f1..b17d8baa 100644
--- a/lib/tailwindcss/engine.rb
+++ b/lib/tailwindcss/engine.rb
@@ -2,6 +2,15 @@
 
 module Tailwindcss
   class Engine < ::Rails::Engine
+    config.before_configuration do |app|
+      app.config.tailwindcss_rails = ActiveSupport::OrderedOptions.new
+      app.config.tailwindcss_rails.engines = []
+    end
+
+    initializer 'tailwindcss.load_hook' do |app|
+      ActiveSupport.run_load_hooks(:tailwindcss_rails, app)
+    end
+
     initializer "tailwindcss.disable_generator_stylesheets" do
       Rails.application.config.generators.stylesheets = false
     end
diff --git a/lib/tasks/build.rake b/lib/tasks/build.rake
index 7eef75eb..2b6b1ebf 100644
--- a/lib/tasks/build.rake
+++ b/lib/tasks/build.rake
@@ -5,12 +5,11 @@ namespace :tailwindcss do
     verbose = args.extras.include?("verbose")
 
     command = Tailwindcss::Commands.compile_command(debug: debug)
-    Tailwindcss::Commands.enhance_command(command) do |transformed_command|
-      env = Tailwindcss::Commands.command_env(verbose: verbose)
-      puts "Running: #{Shellwords.join(command)}" if verbose
+    env = Tailwindcss::Commands.command_env(verbose: verbose)
+    puts "Running: #{Shellwords.join(command)}" if verbose
 
-      system(env, *command, exception: true)
-    end
+    system(env, *command, exception: true)
+    Tailwindcss::Commands.remove_tempfile!
   end
 
   desc "Watch and build your Tailwind CSS on file changes"
@@ -21,14 +20,14 @@ namespace :tailwindcss do
     verbose = args.extras.include?("verbose")
 
     command = Tailwindcss::Commands.watch_command(always: always, debug: debug, poll: poll)
-    Tailwindcss::Commands.enhance_command(command) do |transformed_command|
-      env = Tailwindcss::Commands.command_env(verbose: verbose)
-      puts "Running: #{Shellwords.join(command)}" if verbose
+    env = Tailwindcss::Commands.command_env(verbose: verbose)
+    puts "Running: #{Shellwords.join(command)}" if verbose
 
-      system(env, *command)
-    end
+    system(env, *command)
   rescue Interrupt
     puts "Received interrupt, exiting tailwindcss:watch" if args.extras.include?("verbose")
+  ensure
+    Tailwindcss::Commands.remove_tempfile!
   end
 end
 
diff --git a/test/lib/tailwindcss/commands_test.rb b/test/lib/tailwindcss/commands_test.rb
index 2d525f2f..4d1ebd71 100644
--- a/test/lib/tailwindcss/commands_test.rb
+++ b/test/lib/tailwindcss/commands_test.rb
@@ -1,276 +1,254 @@
 require "test_helper"
-require "minitest/mock"
+require "ostruct"
+require "tmpdir"
+require "rails/engine"
 
 class Tailwindcss::CommandsTest < ActiveSupport::TestCase
-  attr_accessor :executable
-
-  def setup
-    super
+  setup do
+    @tmp_dir = Dir.mktmpdir
+    @original_rails = Object.const_get(:Rails) if Object.const_defined?(:Rails)
     @executable = Tailwindcss::Ruby.executable
   end
 
-  test ".compile_command" do
-    Rails.stub(:root, File) do # Rails.root won't work in this test suite
-      actual = Tailwindcss::Commands.compile_command
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "-i")
-      assert_includes(actual, "-o")
+  teardown do
+    FileUtils.rm_rf(@tmp_dir)
+    Tailwindcss::Commands.remove_tempfile! if Tailwindcss::Commands.class_variable_defined?(:@@tempfile)
+    restore_rails_constant
+  end
+
+  test "compile command includes basic options" do
+    with_rails_app do
+      command = Tailwindcss::Commands.compile_command
+
+      assert_equal @executable, command.first
+      assert_includes command, "-i"
+      assert_includes command, "-o"
+      assert_includes command, "--minify"
     end
   end
 
-  test ".compile_command debug flag" do
-    Rails.stub(:root, File) do # Rails.root won't work in this test suite
-      actual = Tailwindcss::Commands.compile_command
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "--minify")
-
-      actual = Tailwindcss::Commands.compile_command(debug: true)
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      refute_includes(actual, "--minify")
+  test "compile command respects debug flag" do
+    with_rails_app do
+      debug_command = Tailwindcss::Commands.compile_command(debug: true)
+      refute_includes debug_command, "--minify"
     end
   end
 
-  test ".compile_command debug environment variable" do
-    begin
-      Rails.stub(:root, File) do # Rails.root won't work in this test suite
-        ENV["TAILWINDCSS_DEBUG"] = ""
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        assert_includes(actual, "--minify")
-
-        actual = Tailwindcss::Commands.compile_command(debug: true)
-        assert_kind_of(Array, actual)
-        assert_includes(actual, "--minify")
-
-        ENV["TAILWINDCSS_DEBUG"] = "any non-blank value"
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        refute_includes(actual, "--minify")
-
-        actual = Tailwindcss::Commands.compile_command(debug: true)
-        assert_kind_of(Array, actual)
-        refute_includes(actual, "--minify")
-      end
+  test "compile command respects TAILWINDCSS_DEBUG env var" do
+    with_rails_app do
+      ENV["TAILWINDCSS_DEBUG"] = "1"
+      command = Tailwindcss::Commands.compile_command
+      refute_includes command, "--minify"
     ensure
-      ENV.delete('TAILWINDCSS_DEBUG')
+      ENV.delete("TAILWINDCSS_DEBUG")
     end
   end
 
-  test ".compile_command when Rails compression is on" do
-    Rails.stub(:root, File) do # Rails.root won't work in this test suite
-      Tailwindcss::Commands.stub(:rails_css_compressor?, true) do
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        refute_includes(actual, "--minify")
-      end
+  test "watch command includes correct options" do
+    with_rails_app do
+      command = Tailwindcss::Commands.watch_command
 
-      Tailwindcss::Commands.stub(:rails_css_compressor?, false) do
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        assert_includes(actual, "--minify")
-      end
+      assert_equal @executable, command.first
+      assert_includes command, "-w"
+      assert_includes command, "--minify"
+      refute_includes command, "-p"
     end
   end
 
-  test ".compile_command when postcss.config.js exists" do
-    Dir.mktmpdir do |tmpdir|
-      Rails.stub(:root, Pathname.new(tmpdir))  do # Rails.root won't work in this test suite
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        assert_equal(executable, actual.first)
-        refute_includes(actual, "--postcss")
-
-        config_file = Rails.root.join("postcss.config.js")
-        FileUtils.touch(config_file)
-        actual = Tailwindcss::Commands.compile_command
-        assert_kind_of(Array, actual)
-        assert_equal(executable, actual.first)
-        assert_includes(actual, "--postcss")
-        postcss_index = actual.index("--postcss")
-        assert_equal(actual[postcss_index + 1], config_file.to_s)
-      end
+  test "watch command with poll option" do
+    with_rails_app do
+      command = Tailwindcss::Commands.watch_command(poll: true)
+      assert_includes command, "-p"
     end
   end
 
-  test ".watch_command" do
-    Rails.stub(:root, File) do # Rails.root won't work in this test suite
-      actual = Tailwindcss::Commands.watch_command
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "-w")
-      refute_includes(actual, "-p")
-      assert_includes(actual, "--minify")
-
-      actual = Tailwindcss::Commands.watch_command(debug: true)
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "-w")
-      refute_includes(actual, "-p")
-      refute_includes(actual, "--minify")
-
-      actual = Tailwindcss::Commands.watch_command(poll: true)
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "-w")
-      refute_includes(actual, "always")
-      assert_includes(actual, "-p")
-      assert_includes(actual, "--minify")
-
-      actual = Tailwindcss::Commands.watch_command(always: true)
-      assert_kind_of(Array, actual)
-      assert_equal(executable, actual.first)
-      assert_includes(actual, "-w")
-      assert_includes(actual, "always")
+  test ".engines_roots when there are engines" do
+    within_engine_configs do |engine1, engine2, engine3|
+      roots = Tailwindcss::Commands.engines_roots
+
+      assert_equal 2, roots.size
+      assert_includes roots, engine1.css_path.to_s
+      assert_includes roots, engine2.css_path.to_s
+      refute_includes roots, engine3.css_path.to_s
     end
   end
 
-  test ".engines_tailwindcss_roots when there are no engines" do
-    Rails.stub(:root, Pathname.new("/dummy")) do
-      Rails::Engine.stub(:subclasses, []) do
-        assert_empty Tailwindcss::Commands.engines_tailwindcss_roots
-      end
+  test ".engines_roots when Rails is not defined" do
+    Object.send(:remove_const, :Rails) if Object.const_defined?(:Rails)
+    assert_empty Tailwindcss::Commands.engines_roots
+  end
+
+  test ".engines_roots when no engines are configured" do
+    with_rails_app do
+      assert_empty Tailwindcss::Commands.engines_roots
     end
   end
 
-  test ".engines_tailwindcss_roots when there are engines" do
-    Dir.mktmpdir do |tmpdir|
-      root = Pathname.new(tmpdir)
-
-      # Create multiple engines
-      engine_root1 = root.join('engine1')
-      engine_root2 = root.join('engine2')
-      engine_root3 = root.join('engine3')
-      FileUtils.mkdir_p(engine_root1)
-      FileUtils.mkdir_p(engine_root2)
-      FileUtils.mkdir_p(engine_root3)
-
-      engine1 = Class.new(Rails::Engine) do
-        define_singleton_method(:engine_name) { "test_engine1" }
-        define_singleton_method(:root) { engine_root1 }
-      end
+  test ".rails_css_compressor? when css_compressor is not configured" do
+    with_rails_app do
+      Rails.application.config.assets.css_compressor = nil
+      refute Tailwindcss::Commands.rails_css_compressor?
+    end
+  end
 
-      engine2 = Class.new(Rails::Engine) do
-        define_singleton_method(:engine_name) { "test_engine2" }
-        define_singleton_method(:root) { engine_root2 }
-      end
+  test ".command_env with verbose flag" do
+    env = Tailwindcss::Commands.command_env(verbose: true)
+    assert_equal "1", env["DEBUG"]
+  end
 
-      engine3 = Class.new(Rails::Engine) do
-        define_singleton_method(:engine_name) { "test_engine3" }
-        define_singleton_method(:root) { engine_root3 }
-      end
+  test ".command_env without verbose flag" do
+    env = Tailwindcss::Commands.command_env(verbose: false)
+    assert_empty env
+  end
 
-      # Create mock specs for engines
-      spec1 = Minitest::Mock.new
-      spec1.expect(:dependencies, [Gem::Dependency.new("tailwindcss-rails")])
-
-      spec2 = Minitest::Mock.new
-      spec2.expect(:dependencies, [Gem::Dependency.new("tailwindcss-rails")])
-
-      spec3 = Minitest::Mock.new
-      spec3.expect(:dependencies, [])
-
-      # Set up file structure
-      # Engine 1: CSS in engine root
-      engine1_css = engine_root1.join("app/assets/tailwind/test_engine1/application.css")
-      FileUtils.mkdir_p(File.dirname(engine1_css))
-      FileUtils.touch(engine1_css)
-
-      # Engine 2: CSS in Rails root
-      engine2_css = root.join("app/assets/tailwind/test_engine2/application.css")
-      FileUtils.mkdir_p(File.dirname(engine2_css))
-      FileUtils.touch(engine2_css)
-
-      # Engine 3: CsS in engine root, but no tailwindcss-rails dependency
-      engine3_css = engine_root2.join("app/assets/tailwind/test_engine3/application.css")
-      FileUtils.mkdir_p(File.dirname(engine3_css))
-      FileUtils.touch(engine3_css)
-
-      find_by_name_results = {
-        "test_engine1" => spec1,
-        "test_engine2" => spec2,
-        "test_engine3" => spec3,
-      }
-
-      Gem::Specification.stub(:find_by_name, ->(name) { find_by_name_results[name] }) do
-        Rails.stub(:root, root) do
-          Rails::Engine.stub(:subclasses, [engine1, engine2]) do
-            roots = Tailwindcss::Commands.engines_tailwindcss_roots
-
-            assert_equal 2, roots.size
-            assert_includes roots, engine1_css.to_s
-            assert_includes roots, engine2_css.to_s
-            assert_not_includes roots, engine3_css.to_s
-          end
-        end
-      end
+  test ".application_css creates tempfile when engines exist" do
+    within_engine_configs do |engine1, engine2|
+      css_path = Tailwindcss::Commands.application_css
+
+      assert_match(/tailwind\.application\.css/, css_path)
+      assert File.exist?(css_path)
 
-      spec1.verify
-      spec2.verify
+      content = File.read(css_path)
+      assert_match %r{@import "#{engine1.css_path}";}, content
+      assert_match %r{@import "#{engine2.css_path}";}, content
+      assert_match %r{@import "#{Rails.root.join('app/assets/tailwind/application.css')}";}, content
     end
   end
 
-  test ".enhance_command when there are no engines" do
-    Dir.mktmpdir do |tmpdir|
-      root = Pathname.new(tmpdir)
-      input_path = root.join("app/assets/tailwind/application.css")
-      output_path = root.join("app/assets/builds/tailwind.css")
+  test ".application_css returns application.css path when no engines" do
+    with_rails_app do
+      expected_path = Rails.root.join("app/assets/tailwind/application.css").to_s
+      assert_equal expected_path, Tailwindcss::Commands.application_css
+    end
+  end
 
-      command = ["tailwindcss", "-i", input_path.to_s, "-o", output_path.to_s]
+  test ".application_css handles tempfile cleanup" do
+    within_engine_configs do
+      css_path = Tailwindcss::Commands.application_css
+      assert File.exist?(css_path)
 
-      Rails.stub(:root, root) do
-        Tailwindcss::Commands.stub(:engines_tailwindcss_roots, []) do
-          Tailwindcss::Commands.enhance_command(command) do |actual|
-            assert_equal command, actual
-          end
-        end
-      end
+      Tailwindcss::Commands.remove_tempfile!
+      refute File.exist?(css_path)
     end
   end
 
-  test ".enhance_command when there are engines" do
-    Dir.mktmpdir do |tmpdir|
-      root = Pathname.new(tmpdir)
-      input_path = root.join("app/assets/tailwind/application.css")
-      output_path = root.join("app/assets/builds/tailwind.css")
+  test "engines can be configured via ActiveSupport.on_load" do
+    with_rails_app do
+      # Create a test engine
+      test_engine = Class.new(Rails::Engine) do
+        def self.engine_name
+          "test_engine"
+        end
 
-      # Create necessary files
-      FileUtils.mkdir_p(File.dirname(input_path))
-      FileUtils.touch(input_path)
+        def self.root
+          Pathname.new(Dir.mktmpdir)
+        end
+      end
 
-      # Create engine CSS file
-      engine_css_path = root.join("app/assets/tailwind/test_engine/application.css")
+      # Create CSS file for the engine
+      engine_css_path = test_engine.root.join("app/assets/tailwind/test_engine/application.css")
       FileUtils.mkdir_p(File.dirname(engine_css_path))
       FileUtils.touch(engine_css_path)
 
-      command = ["tailwindcss", "-i", input_path.to_s, "-o", output_path.to_s]
-
-      Rails.stub(:root, root) do
-        Tailwindcss::Commands.stub(:engines_tailwindcss_roots, [engine_css_path.to_s]) do
-          Tailwindcss::Commands.enhance_command(command) do |actual|
-            # Command should be modified to use a temporary file
-            assert_equal command[0], actual[0]  # executable
-            assert_equal command[1], actual[1]  # -i flag
-            assert_equal command[3], actual[3]  # -o flag
-            assert_equal command[4], actual[4]  # output path
-
-            temp_path = Pathname.new(actual[2])
-            refute_equal command[2], temp_path.to_s  # input path should be different
-            assert_match(/tailwind\.css/, temp_path.basename.to_s)  # should use temp file
-            assert_includes [Dir.tmpdir, '/tmp'], temp_path.dirname.to_s  # should be in temp directory
-
-            # Check temp file contents
-            temp_content = File.read(temp_path)
-            expected_content = <<~CSS
-            @import "#{engine_css_path}";
-            @import "#{input_path}";
-          CSS
-            assert_equal expected_content.strip, temp_content.strip
+      # Create application-level CSS file
+      app_css_path = Rails.root.join("app/assets/tailwind/test_engine/application.css")
+      FileUtils.mkdir_p(File.dirname(app_css_path))
+      FileUtils.touch(app_css_path)
+
+      # Register the engine
+      Rails::Engine.descendants << test_engine
+
+      # Store the hook for later execution
+      hook = nil
+      ActiveSupport.on_load(:tailwindcss_rails) do
+        hook = self
+        Rails.application.config.tailwindcss_rails.engines << "test_engine"
+      end
+
+      # Trigger the hook manually
+      ActiveSupport.run_load_hooks(:tailwindcss_rails, hook)
+
+      # Verify the engine is included in roots
+      roots = Tailwindcss::Commands.engines_roots
+      assert_equal 1, roots.size
+      assert_includes roots, app_css_path.to_s
+    ensure
+      FileUtils.rm_rf(test_engine.root) if defined?(test_engine)
+      FileUtils.rm_rf(File.dirname(app_css_path)) if defined?(app_css_path)
+    end
+  end
+
+  private
+    def with_rails_app
+      Object.send(:remove_const, :Rails) if Object.const_defined?(:Rails)
+      Object.const_set(:Rails, setup_mock_rails)
+      yield
+    end
+
+    def setup_mock_rails
+      mock_engine = Class.new do
+        class << self
+          attr_accessor :engine_name, :root
+
+          def descendants
+            @descendants ||= []
+          end
+        end
+      end
+
+      mock_rails = Class.new do
+        class << self
+          attr_accessor :root, :application
+
+          def const_get(const_name)
+            return Engine if const_name == :Engine
+            super
           end
         end
       end
+
+      mock_rails.const_set(:Engine, mock_engine)
+      mock_rails.root = Pathname.new(@tmp_dir)
+      mock_rails.application = OpenStruct.new(
+        config: OpenStruct.new(
+          tailwindcss_rails: OpenStruct.new(engines: []),
+          assets: OpenStruct.new(css_compressor: nil)
+        )
+      )
+      mock_rails
+    end
+
+    def restore_rails_constant
+      Object.send(:remove_const, :Rails) if Object.const_defined?(:Rails)
+      Object.const_set(:Rails, @original_rails) if @original_rails
+    end
+
+    def within_engine_configs
+      engine_configs = create_test_engines
+      with_rails_app do
+        Rails.application.config.tailwindcss_rails.engines = %w[test_engine1 test_engine2]
+
+        # Create and register mock engine classes
+        engine_configs.each do |config|
+          engine_class = Class.new(Rails::Engine)
+          engine_class.engine_name = config.name
+          engine_class.root = Pathname.new(config.root)
+          Rails::Engine.descendants << engine_class
+        end
+
+        yield(*engine_configs)
+      end
+    end
+
+    def create_test_engines
+      [1, 2, 3].map do |i|
+        engine = OpenStruct.new
+        engine.name = "test_engine#{i}"
+        engine.root = File.join(@tmp_dir, "engine#{i}")
+        engine.css_path = File.join(@tmp_dir, "app/assets/tailwind/test_engine#{i}/application.css")
+        FileUtils.mkdir_p(File.dirname(engine.css_path))
+        FileUtils.touch(engine.css_path)
+        engine
+      end
     end
-  end
 end