CINXE.COM
Mojolicious - Perl real-time web framework
<!doctype html><html> <head> <link rel="apple-touch-icon" href="/mojolicious/touch-icon.png"> <link rel="apple-touch-icon" sizes="152x152" href="/mojolicious/touch-icon-152x152.png"> <link rel="apple-touch-icon" sizes="167x167" href="/mojolicious/touch-icon-167x167.png"> <link rel="apple-touch-icon" sizes="180x180" href="/mojolicious/touch-icon-180x180.png"> <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="Mojolicious" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>Mojolicious - Perl real-time web framework</title> <script src="/mojolicious/jquery/jquery.js"></script> <script src="/mojolicious/highlight.js/highlight.min.js"></script> <link href="/mojolicious/highlight.js/highlight-mojo-light.css" rel="stylesheet"> <script>hljs.initHighlightingOnLoad();</script> <script src="/mojolicious/bootstrap/bootstrap.js"></script> <link href="/mojolicious/bootstrap/bootstrap.css" rel="stylesheet"> <link href="/mojolicious/fontawesome/fontawesome.css" rel="stylesheet"> <link href="/app.css?v=3" rel="stylesheet"> <link href="/mojolicious.css" rel="stylesheet"> </head> <body><div id="mojo-fun"> <a href="https://metacpan.org/release/Mojolicious"> <img src="/mojolicious/unicorn.png"> </a> <img id="mojo-balloon" src="/mojolicious/balloon.png"> </div> <header> <nav class="navbar navbar-expand-lg navbar-dark mojobar"> <a href="https://mojolicious.org" id="mojobar-brand" class="navbar-brand"> <picture> <img src="/mojo/logo-white.png" srcset="/mojo/logo-white-2x.png 2x"> </picture> </a> <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div id="navbarNav" class="collapse navbar-collapse"> <ul class="navbar-nav mr-auto"> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Documentation </a> <div class="dropdown-menu" aria-labelledby="navbarDropdown"> <a class="dropdown-item" href="https://docs.mojolicious.org">Overview</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Tutorial">Tutorial</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Growing">Growing</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Routing">Routing</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Rendering">Rendering</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Testing">Testing</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Cookbook">Cookbook</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/Contributing">Contributing</a> <a class="dropdown-item" href="https://docs.mojolicious.org/Mojolicious/Guides/FAQ">FAQ</a> <div class="dropdown-divider"></div> <a class="dropdown-item" href="https://docs.mojolicious.org#API">API</a> </div> </li> <li class="nav-item dropdown"> <a class="nav-link dropdown-toggle" href="#" id="communityDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> Community </a> <div class="dropdown-menu" aria-labelledby="communityDropdown"> <a class="dropdown-item" href="https://web.libera.chat/#mojo">IRC</a> <a class="dropdown-item" href="https://forum.mojolicious.org">Forum</a> <a class="dropdown-item" href="https://fosstodon.org/@mojolicious">Mastodon</a> <a class="dropdown-item" href="https://www.linkedin.com/groups/8963713/">LinkedIn</a> <a class="dropdown-item" href="https://github.com/mojolicious/mojo/wiki">Wiki</a> <a class="dropdown-item" href="https://metacpan.org/release/Mojolicious/">CPAN</a> </div> </li> <li class="nav-item"> <a class="nav-link" href="https://github.com/mojolicious/mojo/">Contribute on GitHub</a> </li> </ul> <a class="navbar-brand" href="https://mojojs.org"> <picture> <img src="/mojolicious/mojojs-white.png" srcset="/mojolicious/mojojs-white-2x.png 2x"> </picture> </a> <form action="https://www.google.com/cse" target="_blank" class="form-inline my-2 my-lg-0"> <input name="cx" type="hidden" value="014527573091551588235:pwfplkjpgbi"> <input name="ie" type="hidden" value="UTF-8"> <input name="q" placeholder="Search..." type="search"> </form> </div> </nav> </header> <div class="container"> <div class="row flex-wrap"> <main class="col-sm-12 col-md-8 col-lg-10 py-md-3 pl-md-5"> <div class="mojo-intro"> <div class="mojo-fortune"> <h1> 9 out of 10 penguins recommend Mojolicious! </h1> <p> Mojolicious is a fresh take on <b>Perl</b> web development, based on years of experience developing the Catalyst framework, and utilizing the latest web standards and technologies. You can get started with your project quickly, with a framework that grows with your needs. </p> <p> The Mojo stack provides a consistent set of components that can be used in any project. The guides cover most aspects of using the framework and the components have comprehensive reference documentation. Mojolicious is a real-time web framework, which allows a new class of web applications using WebSockets and having long-running requests without blocking. </p> <p>Join us now, and be a part of a friendly and knowledgeable community of developers!</p> </div> <h2>Features</h2> <div class="row"> <div class="col-md"> <ul> <li> Most <a href="https://metacpan.org/favorite/leaderboard">popular</a> distribution on <b>CPAN</b>. <i class="fa-solid fa-heart"></i> </li> <li> An amazing <b>real-time web framework</b>, allowing you to easily grow single file prototypes into well-structured MVC web applications. <ul> <li> Everything you need to build cloud-native web applications for state of the art container environments. </li> <li> Powerful out of the box with RESTful routes, plugins, commands, Perl-ish templates, content negotiation, session management, form validation, testing framework, static file server, CGI/<a href="http://plackperl.org" target="_blank">PSGI</a> detection, first class Unicode support and much more for you to discover. </li> </ul> </li> <li> A powerful <b>web development toolkit</b>, that you can use for all kinds of applications, independently of the web framework. <ul> <li> Full stack HTTP and WebSocket client/server implementation with IPv6, TLS, SNI, IDNA, HTTP/SOCKS5 proxy, UNIX domain socket, Comet (long polling), Promises/A+, async/await, keep-alive, connection pooling, timeout, cookie, multipart and gzip compression support. </li> <li> Built-in non-blocking I/O web server, supporting multiple event loops as well as optional pre-forking and hot deployment, perfect for building highly scalable web services. </li> <li>JSON and HTML/XML parser with CSS selector support.</li> </ul> </li> <li> Very clean, portable and object-oriented pure-Perl API with no hidden magic and no requirements besides Perl 5.26.0 (versions as old as 5.16.0 can be used too, but may require additional CPAN modules to be installed) </li> <li> Also available for <a href="https://mojojs.org">JavaScript</a>. </li> <li> Fresh code based upon years of experience developing <a href="http://catalyst.perl.org" target="_blank">Catalyst</a>, free and open source. </li> <li> Hundreds of 3rd party <a href="https://metacpan.org/requires/distribution/Mojolicious">extensions</a> and high quality spin-off projects like the <a href="https://minion.pm">Minion</a> job queue. </li> </ul> </div> <div class="col-xs mojo-promotion"> <a class="undecorated" href="https://leanpub.com/mojo_web_clients/"> <img src="/mojolicious/books.png" alt="Get Books"> </a> <br> <a class="undecorated" href="https://shop.spreadshirt.com/kraih/"> <img src="/mojolicious/t-shirts.png" alt="Get T-Shirts"> </a> </div> </div> <div class="mojo-install"> <h2>Installation</h2> <p>All you need is a one-liner, it takes less than a minute.</p> <pre class="mojo-terminal"><code class="nohighlight">$ curl -L https://cpanmin.us | perl - -M https://cpan.metacpan.org -n Mojolicious</code></pre> <p> We recommend the use of a <a href="http://perlbrew.pl" target="_blank">Perlbrew</a> environment. </p> </div> <div class="mojo-start"> <h2>Getting Started</h2> <p>These three lines are a whole web application.</p> <pre><code>use Mojolicious::Lite; get '/' => {text => 'I ♥ Mojolicious!'}; app->start;</code></pre> <p> To run the example with the built-in development web server, just put the code into a file and start it with <code>morbo</code>. </p> <pre class="mojo-terminal"><code class="nohighlight">$ morbo hello.pl Web application available at http://127.0.0.1:3000</code></pre> <p> Test it with any HTTP client you prefer. </p> <pre class="mojo-terminal"><code class="nohighlight">$ curl http://127.0.0.1:3000/ I ♥ Mojolicious!</code></pre> </div> <div class="mojo-tape"> <h2>Duct tape for the HTML5 web</h2> <p> Use all the latest Perl and HTML features in beautiful single file prototypes like this one, and <a href="https://docs.mojolicious.org/Mojolicious/Guides/Growing#Differences">grow</a> them easily into well-structured <b>Model-View-Controller</b> web applications. </p> <pre><code>use Mojolicious::Lite -signatures; # Render template "index.html.ep" from the DATA section get '/' => sub ($c) { $c->render(template => 'index'); }; # WebSocket service used by the template to extract the title from a web site websocket '/title' => sub ($c) { $c->on(message => sub ($c, $msg) { my $title = $c->ua->get($msg)->result->dom->at('title')->text; $c->send($title); }); }; app->start; __DATA__ @@ index.html.ep % my $url = url_for 'title'; <script> const ws = new WebSocket('<%= $url->to_abs %>'); ws.onmessage = function (event) { document.body.innerHTML += event.data }; ws.onopen = function (event) { ws.send('https://mojolicious.org') }; </script></code></pre> </div> <div class="mojo-more"> <img class="mojo-butterfly" src="/mojolicious/butterfly.png"> <h1>Want to know more?</h1> <p> Take a look at our excellent <a href="https://docs.mojolicious.org">documentation</a>! </p> </div> </div> </main> </div> </div> <footer> <div class="container-fluid p-3 mojo-footer"> <div class="row"> <div class="col-sm align-self-center text-center mojo-free"> <b>Free</b> and <b>Open Source</b>. </div> <div class="col-sm align-self-center text-center mojo-copy"> <i class="far fa-copyright"></i> 2008-2023 Sebastian Riedel and the <a href="https://docs.mojolicious.org/Mojolicious#AUTHORS">Mojolicious contributors</a>. </div> <div class="col-sm align-self-center text-center mojo-social"> <a alt="GitHub" href="https://github.com/mojolicious/mojo"><i class="fab fa-github-alt"></i></a> <a alt="Mastodon" rel="me" href="https://fosstodon.org/@mojolicious"><i class="fab fa-mastodon"></i></a> <a alt="LinkedIn" href="https://www.linkedin.com/groups/8963713/"><i class="fab fa-linkedin"></i></a> </div> </div> </div> </footer> <script> $(window).on("mousemove", function (e) { const height = $(document).height(); const positionY = -(height - 2 * e.screenY) / height; const width = $(document).width(); const positionX = -(width - 2 * e.screenX) / width; $("#mojo-balloon").css({ "right": 10 + positionX + "%", "top" : 220 + (positionY * -25) + "px"} ); }); $(window).on("mousemove", function (e) { const width = $(document).width(); const position = -(width - 2 * e.screenX) / width; $("#mojo-fun").css({"backgroundPosition": 0 + (position * 3) + "px 0"}); }); </script> </body> </html>