As a follow up, I encountered the following problem when writing some D2 plugins: only the hooks of the last loaded plugin are kept, the others are lost. See the minimal example below. App: ## #!/usr/bin/env perl use FindBin; use lib "$FindBin::Bin/../lib"; use Dancer2; use Dancer2::Plugin::Second; use Dancer2::Plugin::First; our $VERSION = '0.1'; hook "first_after" => sub { debug "first after"; }; hook "first_before" => sub { debug "first before"; }; hook "second_after" => sub { debug "second after"; }; hook "second_before" => sub { debug "second before"; }; get '/' => sub { test; other_test; return "OK"; }; dance; ## First.pm package Dancer2::Plugin::First; use strict; use warnings; use Dancer2::Plugin; register_hook 'first_after'; register_hook 'first_before'; register test => sub { my $dsl = shift; execute_hook("first_before"); execute_hook("first_after"); }; register_plugin; 1; ## Second.pm package Dancer2::Plugin::Second; use strict; use warnings; use Dancer2::Plugin; register_hook 'second_after'; register_hook 'second_before'; register other_test => sub { my $dsl = shift; execute_hook("second_before"); execute_hook("second_after"); }; register_plugin; 1; ## end (also attached) When starting the app it dies: Invalid hook name `second_after' at /home/melmoth/perl5/perlbrew/perls/perl-5.16.3/lib/site_perl/5.16.3/Dancer2/Core/DSL.pm line 129. I inserted some debug into Core::DSL and this is the list of the hooks it's recognizing: $VAR1 = { 'before_error_render' => 'core.error.before', 'on_route_exception' => 'core.app.route_exception', 'after_error_render' => 'core.error.after', 'before_error_init' => 'core.error.init', 'after_serializer' => 'engine.serializer.after', 'first_before' => 'plugin.first.first_before', 'after' => 'core.app.after_request', 'init_error' => 'core.error.init', 'after_error' => 'core.error.after', 'before_error' => 'core.error.before', 'before_layout_render' => 'engine.template.before_layout_render', 'before' => 'core.app.before_request', 'after_request' => 'core.app.after_request', 'after_file_render' => 'handler.file.after_render', 'before_template_render' => 'engine.template.before_render', 'before_serializer' => 'engine.serializer.before', 'after_layout_render' => 'engine.template.after_layout_render', 'first_after' => 'plugin.first.first_after', 'before_file_render' => 'handler.file.before_render', 'before_request' => 'core.app.before_request', 'after_template_render' => 'engine.template.after_render' }; No trace of the second_after, second_before. If I invert the order of the loading, it dies on "first_after". Using only one of the two plugins appears fine. Any clue? Thanks in advance and best wishes -- Marco