Consider this trivial module, Foo.pm: package Foo; require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw(foo); use Dancer2; sub foo { map { "You gave me '$_', right?" } @_; } 1; ...and this trivial test program: #!/usr/bin/env perl use Foo; print join "\n", foo("foo", "bar"); If you run it, it will complain that &main::foo is undefined. Yet, it is unconditionally exported from package Foo by Exporter, since we've used @EXPORT. (The symptom doesn't change if you use @EXPORT_OK and import &foo explicitly, though.) The fix is easy: comment out the "use Dancer2" line. Why does that help? Why is Dancer2 roaching my module's exports list? Does it have something to do with the way Dancer exports DSL keywords into the global namespace? This is not a real solution, anyway. There is a real "Foo" module in my program that does useful work, and when I pound out the "use Dancer2" line in that module, all of my static content stops being served. Dancer tries to treat everything like a route. It's like the appdir setting isn't getting defined correctly. I tried to test that guess, putting this in one of the route handlers: debug "APPDIR: ", Dancer2::Config::setting('appdir'), "\n"; That just gets me an undefined subroutine error in the browser. I checked Dancer/Config.pm to make sure that routine really exists, as the docs claim, and it does seem to. Is this what you guys mean by "alpha"? :)