I've been using literate-programming for a decade now to do my side web projects (using a tool I wrote myself, of course, as tradition dictates in the LP space: https://github.com/jostylr/literate-programming ). I find it really useful as a project management tool in dealing with the chaos of several different languages, build tools, etc. With HTML, I've used markdown for text content, pug for more structural setups, plain HTML for header boilerplate, all weaved into the same output document that is just plain HTML. It also is often useful for splitting css between a main site sheet vs local to a file (e.g., a lot of css styling on the main landing page is different than the other content-based pages of a site, at least back when websites had content).

I've also found it useful when essentially plugging in data or HTML fragments into JavaScript. I can quickly write a trivial dsl that takes in the data in a convenient form and transforms it into a convenient code version. A variant of the transformational technique is when similar code is almost the same, but just needs a little subbing. I can write a single block covering most of the commonality, and then sub in the differences. For example, if writing some arithmetic operator function code, replacing '+' with the other operators.

An aspect I also love about the approach is having two views of the code. The LP view is more of an outline with blocks subbing in, with some transformations going on. The compiled LP version is one where you can see all the code in full context, minimizing the jumping around at that level, something that cannot be achieved with a bunch of functional calls.

Over the last few weeks, I have started to learn Elixir. I have noticed that I feel less drawn to use literate-programming for that language. It feels like it is so well designed that literate-programming is almost redundant for it. I am trying to figure out justifying that statement, but it is still early days for me in that language. But it feels like, for instance, the matching on function parameters so that one can avoid if-else if-...-else constructs cuts down on a lot of boilerplate stuff. Admittedly, JavaScript has a lot less of that as well nowadays with all the new language constructs. Maybe it is just about Elixir being a functional language with the safety and little overhead of calling functions that make it more attractive to use functions as the outlining / reordering mechanism. Also, the pipe operator allows steps of transformations to be done easily and clearly, which is super helpful. And having tests run from the doc code is something to embrace, further making the separate commenting in LP less favorable in the Elixir context.

One huge downside of LP is that it allows the dictates of a given language to be worked around, making it harder for others to follow up with the work. Ideally the text of the LP helps with that, but it still is a barrier. This seems less of a problem in the front-end web world because that is just a mess of competing notions, but in something cohesively designed with sensible standards that the community follows (my impression of Elixir), it would become a much bigger downside to strike out on your own path.