clear light bulb planter on gray rock

Twitter recently recommended a tweet to me (all hail the algorithm) touting what the author viewed as the top 5 web development stacks.”

JavaScript/​Node.js options dominated the four-​letter acronyms as expected, but the fifth one surprised me: LAMP, the combination of the Linux operating system, Apache web server, MySQL relational database, and Perl, PHP, or Python programming languages. A quick web search for similar lists yielded similar results. Clearly, this meme (in the Dawkins sense) has outlasted its popularization by tech publisher O’Reilly in the 2000s.

Originally coined in 1998 during the dot-​com” bubble, I had thought that the term LAMP” had faded with developers in the intervening decades with the rise of language-​specific web frameworks for:

Certainly on the Perl side (with which I’m most familiar), the community has long since recommended the use of a framework built on the PSGI specification, deprecating 1990s-​era CGI scripts and the mod_​perl Apache extension. Although general-​purpose web servers like Apache or Nginx may be part of an overall system, they’re typically used as proxies or load balancers for Perl-​specific servers either provided by the framework or a third-​party module.

Granted, PHP still relies on web server-​specific modules, APIs, or variations of the FastCGI protocol for interfacing with a web server. And Python web applications typically make use of its WSGI protocol either as a web server extension or, like the Perl examples above, as a proxied standalone server. But all of these are deployment details and do little to describe how developers implement and extend a web application’s structure.

Note how the various four-​letter JavaScript stacks (e.g., MERN, MEVN, MEAN, PERN) differentiate themselves mostly by frontend framework (e.g., Angular, React, Vue.js) and maybe by the (relational or NoSQL) database (e.g., MongoDB, MySQL, PostgreSQL). All however seem standardized on the Node.js runtime and Express backend web framework, which could, in theory, be replaced with non-​JavaScript options like the more mature LAMP-​associated languages and frameworks. (Or if you prefer languages that don’t start with P”, there’s C#, Go, Java, Ruby, etc.)

My point is that LAMP” as the name of a web development stack has outlived its usefulness. It’s at once too specific (about operating system and web server details that are often abstracted away for developers) and too broad (covering three separate programming languages and not the frameworks they favor). It also leaves out other non-​JavaScript back-​end languages and their associated frameworks.

The question is: what can replace it? I’d propose NoJS” as reminiscent of NoSQL,” but that inaccurately excludes JavaScript from its necessary role in the front-​end. NJSB” doesn’t exactly roll off the tongue, either, and still has the same ambiguity problem as LAMP.”

How about pithy sort-​of-​acronyms patterned like database-​frontend-​backend? Here are some Perl examples:

  • MRDancer: MySQL, React, and Dancer (I use this at work. Yes, the M could also stand for MongoDB. Naming things is hard.)
  • MRMojo: MongoDB, React, and Mojolicious
  • PACat: PostgreSQL, Angular, and Catalyst
  • etc.

Ultimately it comes down to community and industry adoption. If you’re involved with back-​end web development, please let me know in the comments if you agree or disagree that LAMP” is still a useful term, and if not, what should replace it.

text

Last week’s article received a comment on a private Facebook group that amounted to just use JavaScript’s built-​in formatting.” So what would that look like?

#!/usr/bin/env perl

use Mojolicious::Lite -signatures;
use DateTime;

get '/' =>
    sub ($c) { $c->render( template => 'index', date => DateTime->today ) };

helper localize_date => sub ( $c, $date = DateTime->today, $style = 'full' ) {
    my $date_params = join ',' => $date->year, $date->month_0, $date->day;
    return
        qq<new Date($date_params).toLocaleString( [], {dateStyle: "$style"})>;
};

app->start;
__DATA__
@@ index.html.ep
% layout 'default';
% title 'Today';
<ul>
    <li><script>
        document.write(<%== localize_date $date %>)
    </script></li>
    % for my $style ( qw(long medium short) ) {
    <li><script>
        document.write(<%== localize_date $date, $style %>)
    </script></li>
    % }
</ul>
@@ layouts/default.html.ep
<!DOCTYPE html>
<html>
    <head><title><%= title %></title></head>
    <body><%= content %></body>
</html>

It’s structured much like the Perl-​only solution, with a default "/" route and a localize_date Mojolicious helper to do the formatting. I opted to output a piece of JavaScript from the helper on lines 11 through 14 since it could be repeated several times in a document. You could instead declare a function in the default layout’s HTML <head> on line 38 that would receive a date and a formatting style, outputting the resulting formatted date.

In the template’s list from lines 22 through 31 I decided to use JavaScript document.write method calls to add our generated code. This has a slew of caveats but works for our example here.

Worth noting is the double equals sign (<%== %>) when embedding a Perl expression. This prevents Mojolicious from XML-​escaping special characters, e.g., replacing "quotes" with &quot;, <angle brackets> with &lt; and &gt;, etc.. This is important when returning HTML and JavaScript code.

I also chose to use the JavaScript Date object’s toLocaleString() method for my formatting on line 12. There are other ways to do this:

  • Date objects also have a toLocaleDateString method. However, Mozilla has a performance note that states it’s better to use the Intl.DateTimeFormat object’s format property.
  • But Intl.DateTimeFormats browser support stands at about 70%, leaving out Safari (that’s Mac, iPhone, and iPad) and Internet Explorer users.
  • There are JavaScript libraries and polyfills to address these issues, but I’m trying to keep this example simple.

Note that line 10 builds the parameters for JavaScript’s Date constructor using the year, month_0, and day methods of our Perl DateTime object; month_0 because the Date constructor takes its month as an integer from 0 to 11 rather than 1 to 12. JavaScript Dates can be constructed in many ways; this seemed the simplest without having to explain things like epochs and inconsistent parsing.

Why are we using Perl DateTimes and a helper anyway? I’m assuming that our dates are coming from the backend of our application, possibly inflated from a database column. If your dates are strictly on the frontend, you might decide to put your formatting code there in a JavaScript function, perhaps using a JavaScript-​based templating library.

The bottom line is to do whatever makes sense for your situation. I prefer the Perl solution because I like the language and its ecosystem and perhaps have acclimated to its quirks. The complications of JavaScript browser support, competing frameworks, and layers of tooling make my head hurt. Despite this, I’m still learning; if you have any comments or suggestions, please leave them below.