Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Constructive thoughts on Dancer2 v Mojolicious

by Anonymous Monk
on Jun 03, 2020 at 18:33 UTC ( #11117667=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I assume both frameworks are mature at this point, are all things equal between these two frameworks, or are there advantages to one over the other?

What has your experience been? or put another way, what made you choose one over the other?

  • Comment on Constructive thoughts on Dancer2 v Mojolicious

Replies are listed 'Best First'.
Re: Constructive thoughts on Dancer2 v Mojolicious
by Your Mother (Archbishop) on Jun 03, 2020 at 18:54 UTC

    Disclaimer, I tried Dancer2—well, Dancer—early on and didn’t like it and the only time I went back since v2 to look again—from a problem/question posted here—I saw code that I thought was… smelly, so stopped again without retrying. Plenty of good hackers like it so don’t discount it merely on my experience. That said, I am extremely experienced. :P I’ve written three blog platforms and two of my own webframeworks.

    Mojo is a full toolset. Its testing and content parsing in particular are deeply valuable. I have still not written anything serious with Mojo because I know Catalyst and and naked Plack and my own nonsense well. I would almost certainly choose Mojo for a real, shared or public, project specifically because it makes test driven development semi-trivial and it is keeping up with security and new technology better than the other frameworks. It also just feels Perly, terse and DWIM. Sidenote to that, the chief architect of Mojo also created Catalyst and had one other framework between so Mojo represents a LOT of accumulated wisdom applied to the workflow of writing and maintaining web applications.

      For the record Dancer and Dancer2 are completely separate toolkits. Dancer2 is *not* version 2 of Dancer. Dancer has been described by the project leads as "a big collection of abuses of globals." On the other hand, Dancer2 is by far the most Perlish framework I have used.

      Mojolicious has also undergone breaking changes, but uses major version numbers, and then deprecates/uses an EOL schedule for earlier versions. So you wind up having to pin a version anyway.

      I use Mojo at work and it works. I dislike a lot of things about it, all mostly centered around the personality/culture of its core development group. For example, Mojo 8 includes, which despite its doc breaks our code using can ...

      monkey_patch $dyn_pkg, 'can', sub { my ($self, $method, @rest) = @_; # Delegate to our parent's "can" if there is one, without breaking + if not my $can = $self->$caller_can($method, @rest); return undef unless $can; no warnings 'once'; my $h = do { no strict 'refs'; *{"${dyn_pkg}::${method}"}{CODE} }; return $h && $h eq $can ? undef : $can;
      Talk about EETOOMUCHMAGIC!

      Adopting Mojo is a bit like getting jumped into the mob: there's no exit, and the rules are the rules. I find Dancer2 app development to be much more intuitive, light, and fun.

      The way forward always starts with a minimal test.

        I did qualify my take with saying good devs like Dancer!

        Magic is concerning but if the dev team is behind it, I don’t mind. That code looks clean and safe to me.

        So you wind up having to pin a version anyway.

        Yeah, some of the speed releases early on in Mojo are what kept me from investigating it for years. Plus I can’t use it at work because *SIGH* we’re still on 5.8. That said, professional software should specifically set every version of every package it contains. A good test suite generally makes updates to libraries easy; or at least quickly finds what can’t or shouldn’t be updated.

        It was basic Dancer2 backend code that kept me from trying it again: badly scoped variables. And again, the reason it took many years to even consider this stuff is I’m pretty thermally energetic feces with Catalyst. :P

        >Adopting Mojo is a bit like getting jumped into the mob: there's no exit, and the rules are the rules.

        Never thought of it quite this way, but now that you mention it I got the same feeling from early Perl frameworks like PHP and Mason, not to mention this sentiment applies to Moose and it's elk.

Re: Constructive thoughts on Dancer2 v Mojolicious
by alexander_lunev (Pilgrim) on Jun 04, 2020 at 06:22 UTC
    I don't know anything about Dancer or Dancer2, really. Because when I first start using Mojolicious, I loved it with my heart and stop searching. I've done 10+ projects with Mojolicious, for Internet and localhost, half of them on Windows, and I just can't think of anything else because everything I need already there, be it Mojo::JSON or Mojo::WebSocket or Mojo::UserAgent or Mojo::IOLoop. I'm using various Vue.js frameworks for frontend (be it vanilla Vue.js or more complex Quasar framework) with Mojolicious and this couple is a full toolset for everything I need.

      I'm curious about your setup. The FAQ touches on the potential for some issues, and a note about advanced features which won't work. If you have the time I'd like to hear about your setup/experiences. Thanks.

        I'm using Strawberry Perl, and in most cases I'm not using anything too complex or too UNIX-ish on Windows, at maximum I'm using fork. As for database, it's often SQLite DB (using Mojo::SQLite), there was once a project with database in DBF files, and now I'm writing a project with Firebird SQL server as a database (using DBD::ODBC and Firebird ODBC connector). Frontend is always some flavour of Vue.js.

        To make things more like it's done on Windows, I'm using two files, START.CMD for starting whole project, which is:

        @echo off set PATH=perl;%PATH% perl -Iperl\lib "script/project" pause

        Here's project structure:

        [lib] [perl] [public] [script] [templates] [uploads] db.sqlite db.sqlite-shm db.sqlite-wal init.sql START.CMD project.conf

        Here you see that I rewrite %PATH% variable. It's my Electron-like application harness, in perl dir there's a stripped Strawberry Perl with modules to run on other Windows machines.

        Then there is starter perl script,

        #!perl use Mojo::Base -strict; use Mojo::Server::Morbo; use Mojo::Util qw(extract_usage getopt); my $morbo = Mojo::Server::Morbo->new; my $pid = fork(); if ($pid) { # PARENT $morbo->daemon->listen(["http://*:3000"]); $morbo->run(shift); } else { # CHILD use Socket; my $host = 'localhost'; my $port = '3000'; my $timeout = 30; my $started = 0; while (not $started) { sleep 1; $started = portAlive(); } system("start http://localhost:3000"); exit; sub portAlive { my $proto = getprotobyname('tcp'); my $iaddr = inet_aton($host); my $paddr = sockaddr_in($port, $iaddr); socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || warn "socket: +$!"; eval { local $SIG{ALRM} = sub { die "timeout" }; alarm($timeout); connect(SOCKET, $paddr) || error(); alarm(0); }; if ($@) { close SOCKET || warn "close: $!"; print "$host is NOT listening on tcp port $port.\n"; return 0; } else { close SOCKET || warn "close: $!"; print "$host is listening on tcp port $port.\n"; return 1; } } }

        When Morbo server started, script will start browser with URL of project, and voila. Also, there could be no black CMD.EXE windows at all with wperl.exe + WebSocket + Mojolicious trick:

        $r->websocket('/bus' => sub { my $self = shift; $self->inactivity_timeout(1000); #$log->debug(sprintf 'Client connected: %s', $self->tx); my $id = sprintf "%s", $self->tx; $clients->{$id} = $self->tx; $self->on(message => sub { my ($self, $msg) = @_; for (keys %$clients) { $clients->{$_}->send({json => {message => $msg}}); } }); $self->on(finish => sub { #$log->debug('Client disconnected'); delete $clients->{$id}; Mojo::IOLoop->timer(10 => sub { my $loop = shift; if (not scalar keys %{ $clients }) { #$log->debug('No clients! exiting!'); exit; } else { #$log->debug('Have clients! not exiting!'); } }); }); } );

        When last client disconnects from WebSocket (browser window/tab with project closes) - server exits.

Re: Constructive thoughts on Dancer2 v Mojolicious
by hippo (Chancellor) on Jun 04, 2020 at 21:37 UTC
    are all things equal between these two frameworks

    I don't use either of them. Now and again I go back and have another look as many fellow monks are wont to rave about one or the other but neither has yet enticed me enough to dive in. That said there are clearly some differences between them and that may or may not influence a decision to go with one or the other. It depends largely on which attributes you deem most important.

    Non-core direct deps28none
    Open issues10646
    Issues resolved this year1329
    Metacpan ++115 (47 PAUSErs)427 (181 PAUSErs)
    Last release27th May3rd June
    Non-dev releases this year417
    Test coverage84%90%
    Kwalitee150 (96.88 core)156.25 (96.88 core)
    Reverse deps (direct)168 (148)964 (858)
    LicenceAs PerlArtistic 2

    Numbers correct at time of posting (E&OE). No doubt you can pick other metrics of importance to you. Given the recent releases from both, comparing the smoke tester pass/fail ratio seemed not to be useful (and they both have good records there anyway).

      Thanks hippo,

      As I have stated I use both frameworks both at my job in a big org. The main app is built in Mojo. Personally I choose Dancer2 at work and at home and I have contributed to the project.

      Here's my perspective: none of the metrics you shared are of much use in evaluating the comparative worth of the two projects. Let's take the two most divergent ones, and the two that most embody the philosophical differences between Dancer and Mojo. Both the non-core deps count and the metacpan plusplussers count are in my experience merely indicators of the cult-like nature of Mojolicious. Dancer2 on the other hand is much more like an open source framework.

      Mojo is likely to evolve into an OS at the rate it is reinventing all the wheels. I like my app framework to be more of a scaffold. I want to be able to pick up my entire route-handling codebase and drop it into another scaffold if I choose; no way I can do that with a modern Mojo app.

      Again from my perspective: more dependencies nowadays means (or should mean) that the app is more Perlish, not that it is bloated; fewer releases means it is more stable; open issues is a shame but could easily be housekeeping -- I know from experience that the Mojo core devs are very aggressive in closing tickets with WONT_FIX.

      It's one of those things where Mojo has clearly won the popularity war, but not necessarily because of quality. I used to surf with some guys in SoCal that could surf just as well or better than anyone on the WCT, but either because of circumstantial fate, or because they were more of a spiritual surfer than a competitive shredder, they were less known, even anonymous. Most of them liked it that way, and I know I enjoyed being in the water with them more than with the pros.

      I have way more fun working with Dancer; I find that I am able to be a more expressive developer. But hey, some people use IDEs ... cada cabeza es un mundo ...

      The way forward always starts with a minimal test.
      A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Constructive thoughts on Dancer2 v Mojolicious
by perlfan (Vicar) on Jun 04, 2020 at 02:59 UTC
    It's dealer choice and YMMV, etc. But I will point out that the "hello world" of Dancer2:
    #!/usr/bin/env perl use Dancer2; get '/hello/:name' => sub { return "Why, hello there " . route_parameters->get('name'); }; dance;
    and that of that of mojo are equally dead simple:
    #!/usr/bin/env perl use Mojolicious::Lite; get '/' => {text => 'I <3 Mojolicious!'}; app->start;

    Was moving from CGI::Application/::Dispatch (and there from CGI), I tried Dancer2 first and stopped there. I just needed something and it fit the bill. I do like that the route handler in Dancer2 is a subref rather than a hash ref, now looking more closely at the two. What did Dancer2 give me that I wanted so badly? Simple access to routing. As you can see, had I looked at Mojo first I may very well have chosen that.

    Why did I choose CGI::Application over CGI? Because it was not overcomplicated and ridiculous like some of the other frameworks I had to choose from when I was looking. It was also extensible. But it didn't have routes (yes I used CGI::Application::Dispatch for a while happily), and when I learned what routes were, I knew that was the way to go.

    Besides routes, it provided a simple introduction to PSGI. And I really liked the idea of never having to configure httpd again. This meant, control over where, when, and how I deployed the application. Both Dancer2 and Mojo provide this. Mojo does seem more suited for very precised composition of your application. If I needed all of that, I might (and may very well) give it a shot.

    Here's my advice: no matter what framework you choose between the two, it'll be way better than what our options were in the first part of this century; the trick is to maintain clean separation between your business logic and controllers so that you can easily switch from Dancer2 to Mojo or vice versa (or the next leap in framework evolution) without much effort. By effort, I mean you should not have much if any framework specific bits buried in what you would classify as the essence of your application. This included: templates and other assets, business logic, authentication, database access, and all the stuff you do with it.

      Your two examples are not equivalent. For the Mojolicious app to do the same thing you're doing in the Dancer 2 app, it would look like this:

      #!/usr/bin/env perl use Mojolicious::Lite -signatures; get '/hello/:name' => sub ($c) { $c->render(text => 'Why, hello there ' . $c->param('name')); }; app->start;

      Spruced up to provide the same functionality as the Dancer 2 app, the code looks substantially similar. The two frameworks do have many useful differences. But at the heart of it they're both lightweight web frameworks, and both are quite capable. I prefer Mojolicious too, but some of that is due to familiarity and having used it in production a number of times. I've heard people whine about the Mojolicious framework coming with "too much stuff." I disagree with this premise; it comes complete, and useful, and still in a tarball under 800KB.


        I just copied from both sites directly. Also, you're free to disagree obviously. I just wanted to share my experience. I use Dancer2, so I have decided for myself. Sounds like you have also. One thing that seems to be a common theme is that poeple tend to stop at the one they try first. I think that's an important and interesting effect. That tells you for many, they are equivalent in terms of meeting needs - i.e., "quick start".
Re: Constructive thoughts on Dancer2 v Mojolicious
by Ea (Chaplain) on Jun 08, 2020 at 11:36 UTC
    When I was looking around frameworks, the question that settled my mind was the tutorials. Mojolicious had the Mojocasts which got me hooked from the beginning. (warning: a little dated, Mojo has moved on and the tutorials aren't as up to date)

    Work has been using Dancer2 which is alright. In fact, I find that learning one framework is transferable. The only thing I miss is Test::Mojo. We even use a bit of Mojo::Dom in places.

    There are books on both: Mojolicious Web Clients by brian d foy and Single page applications by Gábor Szabó. Perhaps more importantly, find out which conferences you can get to easily or what the local Perl Mongers are using. That kind of meat-space support is invaluable in getting into the deeper corners of what is possible.

    If you still can't decide, flip a coin and get started. Beat the analysis-paralysis. Best of luck.


    Sometimes I can think of 6 impossible LDAP attributes before breakfast.

    Mojoconf was great!

Re: Constructive thoughts on Dancer2 v Mojolicious
by Anonymous Monk on Jun 04, 2020 at 17:16 UTC
    I worked for many years with an on-line store system that was built using CGI::Application and it worked just fine. Booked hundreds of thousands of dollars in sales every month without a hitch. Both of the frameworks that you mention have plenty of success stories, so, really, it just comes down to your preference. Take a few days to build-out a small subset of your project in each of them and see which one feels better to your sensibilities. You're not going to "make a wrong decision" either way.

      "are there advantages to one over the other? ... What has your experience been? or put another way, what made you choose one over the other?"

      None of your claimed experience or your post answers any of this.

        I was told that more and more news sites start using bots to write articles.

        Is it that far fetched that they trained with a MikeBot here, repeating the same drivel over and over? 🤔


        On second thought that's not likely, bots learn over time and show progress.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

      Your answer is helpful and germane. Maybe just not German.

      You're not going to "make a wrong decision" either way.

      Only if that decision is to go lock, stock, and barrel on the framework koolaid; whatever one chooses. Just need to properly separate the code. A good experiment for this (and deciding, frankly) would be to ensure your application runs in both frameworks. For nostalgia, throw in CGI::Application since that separation of code is easy in that framework also.

        "Your answer is helpful and germane. Maybe just not German."

        No, the 'reply' isn't an answer. It doesn't address any of the points OP specifically asked for advice on, and you are replying to one of the sites worst trolls.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://11117667]
Approved by davies
Front-paged by marto
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (6)
As of 2021-04-21 05:58 GMT
Find Nodes?
    Voting Booth?

    No recent polls found