Hello, I am Yuchen, and I will be talking about how Emacs may be used to save user freedom on the web. I will begin by describing the background issues, followed by solutions outside of Emacs. Then I will move into the main business of describing several ways to address the issues using Emacs, including free clients in Emacs, web browsers, also known as universal clients in Emacs, approaches using Emacs web server and Emacs web framework, which allows one to write an Emacs package and get web web for free, as well as using Emacs as a Firefox extension. OK, let's now move on to the background issues for this topic. Many of you probably already know what is free software. It is a software that respects four user freedoms, including freedom 0, which is the freedom to use, freedom 1 is the freedom to study and modify a program, freedom 2 is the freedom to distribute exact copies of a program, and freedom 3 is the freedom to distribute modified copies. Different environments have different norms with regards to user freedom. For example, GNU Linux distributions default to free software, even though the official kernel Linux contains non-free code, like non-free firmware. What I mean is, people generally expect free software in these environments. There's plenty of free software built on other free software, so generally people can accomplish tasks using free software only. Emacs, by comparison, is even better. It has freedom building, as it is highly customizable with self-documenting configurations. When a list form is evaluated by the user in Emacs, the change is instantly reflected in the environment. Thus, it converts users to hackers effortlessly. From writing setq statements, which is similar to configurations in the majority of other programs, to writing functions, which are building blocks of Elixir features, to writing features and publishing packages, it is a natural progression. In this sense, Emacs perhaps has the most gentle learning curve for hackers. On the other hand, the default license in the Emacs community is GNU General Public License version 3 or later, which is the best free software license apart from the Afero license. Now let's move on to web browsers, which by contrast does not default to freedom. For one thing, free software JavaScript projects default to XBAT, which is also commonly known as the MIT license, which is a less permissive license that could be exploited as developers could write non-free derivatives and subjugate user freedom. This also contributes to the JavaScript trap. Most popular web browsers nowadays simply download and run any JavaScript code requested by the web page. Generally speaking, there are two camps on this issue. One side would say JavaScript is simply part of life, and an integral part of the so-called modern web. Just accept it, and there is no point in fighting it. Indeed, it can be frustrating when greeted by this page requires JavaScript and cookies to continue, or even a blank page when opening a web page while disabling JavaScript. The other camp takes a more principled position and says JavaScript is unnecessary. I mean, people use the web mainly for database-like operations to interact with data stored on other people's computers, like querying, creating, updating, deleting. I mean, 99% of the things happen in getting data, including reading news, watching videos, downloading images, etc., and posting data, including publishing this sort of materials, publishing news comments, videos. Why does this need any programs to do funny computations, right? Modern web browsers are also a pain to use. They are the opposite to Emacs in terms of customization capabilities. Such problems on the client side is the main focus of this talk. On the server side, the issue is known as SAS, service as a software substitute. It is about doing computing for users on other people's computers, which the user has no visibility, let alone control. Examples include translation or photo editing in so-called web applications. Another example would be web applications make recommendations based on user data and suggest what the users read or watch next. On one hand, SAS is an intractable problem because free software is all about user freedom on one's own computer, not someone else's computer. On the other hand, this is also a lesser problem because it has trivial solutions, which is self-hosting and keeping computations local. Wouldn't it be nice to use a photo editing web application, but without the web? Right, now let's move on to solutions outside of Emacs that tackle these problems. There are generally two ways to fix this issue. One is blocking non-free JavaScript, and the other is substituting with free programs. Let's start with blocking. LibreJS, for example, is a Firefox extension blocking non-free, non-trivial JavaScript. It works by intercepting, filtering, or requests for JavaScript, recognizing the ones that are trivial or free, and blocking the execution of the others. As an experiment, I locked the LibreJS output for about two weeks, and during which of all the web pages I loaded, 23 domains have at least some LibreJS-compliant scripts. That is not much, though I did use other means to reduce the scenarios where I need to load web pages with JavaScript in Firefox, like using a text browser like Lynx. Then there's also NoScript, which is like LibreJS, but it blocks all scripts, whether free or non-free, trivial or non-trivial. So the problem with blocking is that blocking with certain scripts and accepting others, there are like, I can think of two problems. One is that it does not help with Freedom1, which is the freedom to allow users to modify a program and use it in place of the original program. And also it does not help when the non-free JavaScript is mandatory for the functioning of the web page. For example, some pages are blank when non-free JavaScript is not executed. So now let's move on to the substitution, the other method. So let's start with UserScript. It is a script, it is a user-specified JavaScript injected to a web page. A typical example of UserScript2 is grease monkey. Another idea is a proxy that replaces scripts in place, that is, sending user-specified scripts as a response to requests for such scripts. So one example would be HackTilo, however you pronounce it. It's a tool that's built on top of MITM proxy. It is supposed to do this. I haven't used grease monkey nor HackTilo for these purposes yet, so I can't say much about these options. So then there are also free clients which replace the whole frontend instead of scripts requested by web pages from the official web clients. People often refer to them as alternative frontend. So YouTube is perhaps the best example as there are so many free clients, including NVIDIA's for the web, YouTube DL and YTDLP on the command line, MPV and VLC as GUI desktop, LibreTube and NewPipe for Android and so on. YouTube DL and YTDLP are especially versatile as they work with many video and audio sites with extractors written in Python, so people can add extractors like extensions. A similar tool would be Woop, short for web outside of the browsers. It is a command line and GUI program that interacts with many web services, even banks. And there are browser extensions that automatically redirect to these clients. For example, Redirector and LibRedirect redirect to the free web clients. One could use OpenWith, another extension, to redirect to free non-web clients, for example by opening YouTube links with MPV. Now let us move to Emacs-based solutions. They are based on the same ideas but using Emacs. First, free clients in Emacs, basically alternative frontends written in Ellipse. There are several advantages, for example integration with other Emacs tools, good for archiving, making use of Emacs libraries, extensibility thanks to Emacs' own extensibility and customizability. Examples include mastodon.el for mastodon, or mastorg for viewing and archiving tools with org, sx for stack exchange, buildbot.el for buildbot, etc. Here's an example of a mastorg displaying the hierarchy of a toot in org. Just wait. Right. So this is the toot itself, this is a first reply, this is a reply to the reply, and so on. And here is an example of opening a stack exchange link using sx. And let's check out the tag. So we can browse stack exchange Emacs sites with ease. The idea is quite simple. Just use APIs to get data and display it in Emacs, or just scrape, like requesting HTML and processing it. An example of scraping is hnreader, which scrapes a hacker news web page's HTML page. An example of scraping is hnreader, which scrapes a hacker news web page's and renders them in org buffers. Here's how hnreader fetches and displays the hacker news front page. And one could go into the comments, which shows a similar hierarchy to mastorg output. And of course, there are limitations for this method, which is not limited to Emacs. There are basically limitations to any ad hoc bespoke clients, which is catch-up games with remote server, which may change the API interface endpoints or even structure of the responses. And this brings us to web browsers in Emacs. Web browsers are universal clients because all sites support browsers. So in a world of no JavaScript, there will be no need to write bespoke clients. In such a world, instead of using JavaScript code to fetch JSON, web developers make server do the heavy lifting and just send the complete HTML over. Okay, back to reality. EWW, the default Emacs browser, is what people refer to as a text browser, even though it is not text only and it supports images too. It is a good solid browser that supports forms, etc. The downside is that it does not support CSS, so the formatting could be a bit ugly sometimes. There are some other browsers in Emacs too, like Emacs-W3M, which is backed by W3M, and Luwak, which is backed by Lynx. Sorry for the naming, by the way. They often consist of a backend that fetches URL and parses HTML. For example, the built-in URL package and the libxml2 binding in Emacs are decent enough. And the frontend that renders the HTML, like SHR or Lynx, etc. There is also an XWidget webkit, but this browser executes JavaScript, so it does not really help in this case. Browser extensions on Emacs are effortless, as they can be written as Emacs packages. For example, one could easily write Elixir scripts with similar functionalities to redirect links to rewrite URLs, or to open, say, a YouTube URL with MPB, but with even more flexibility. For example, here's how one could transform a Zoom link to a dialing number so that it is easier to join a Zoom meeting without running non-free JavaScript. This might still be bad for privacy, but at least it's good for freedom. As mentioned before, one shortcoming of these Emacs-based browsers, Emacs web browsers, is no support for CSS, so the formatting could leave a lot to be desired. Maybe someone would write an Emacs browser package backed by WKHTML2 PDF, which, when opening a URL, it calls WKHTML2 PDF to convert the web page to PDF and opens in, say, PDF view mode of the PDF tools, thus containing formatting, and all the URL clicks resolve to the same actions. Also, WKHTML2 PDF contains a flag that disables JavaScript. Another idea would be to use Firefox as a processor to fetch URLs. Maybe it can be used to pass back the HTML after executing free JavaScript, say, if Firefox has LibreJS installed. This requires Firefox to send back the DOM, which could be achieved using native messaging. More on that later. Alternatively, one could also write a Firefox extension that sends the DOM in an existing tab back to Emacs. But thinking more about it, I don't think this is actually a useful idea, because most of the sites that work under LibreJS also are useful when all JavaScript is blocked. So, this means these sites are viewable under UWW, Luwak, etc. And another issue is that this could also make running non-free JavaScript easier, which is harmful to user freedom. OK, let's move on to the idea of running Emacs as a web server, so that Emacs client packages are web apps serving as alternative frontends. Why would we want to do this? Well, as much as one wants to be always in Emacs, it is not always feasible. For example, one may be on the go and needs to look up something on the phone. On the other hand, Emacs client packages are just alternative frontends but written in Elixir and run in Emacs. With the help of Emacs web server package, we can access Emacs packages on the web. Emacs web server package is not something new, but seems to be underused in the community somehow. OK, let's start with a simple example called hello-emacs. It is pretty straightforward. Just require the web server feature and run ws start to start a server process and send the string hello-emacs to the process regardless of the request. As you can see, it is going to be available at port 9000 of localhost. Let's try it out. We need to first evaluate this code block. And it works. To stop a server, just run ws stop on the web server object. Let's evaluate. Yep, it stopped. OK, now let's move on to something funny that you should never run on the public web. I call it yolo.el. It uses HTMLize to make any Emacs buffer available on the web. Let's try it out. Just require the thing and start the server by yolo start. And it's available at port 9999. By default, the root domain shows the splash screen which needs to be available. Running display splash screen ensures that, but here I've already run it. So let's have a look. And here we have the splash screen. Emacs tutorial and such. Unfortunately, none of these links work, which is something we will revisit later. So, to show an arbitrary buffer, just use the buffer name as a path. For example, the slide has the buffer name web.org. So we can display it. And let's try something fancier, like the main page of ffmpeg. So this is the main page of ffmpeg. And the buffer name is a bit more complicated. So I have the URL available here. It's missing a star. It's pretty neat if you ask me. And, yeah, what else? Well, we can also browse EWW in Firefox. So, for example, let's check out gnu.org. And note that the buffer name is EWW with stars. So, ah, it works. And it has all the graphics even. And now, how about we do it the other way around? So we load the current slide web.org using this funny thing. And it works. Not as nice as the org buffer, though. Right, and now that gives me some funny idea. So I'm a firm believer that memes are meant to be enjoyed in silence rather than read out loud. So I will jump straight to trying this idea, which is loading the EWW buffer URL with EWW itself. Loading, loading, loading. Spoiler alert, it never loads. So that concludes the demo. And so we can stop the server, web server, with YOLO stop. So one could extend YOLO to serve arbitrary Emacs commands, making it even more dangerous. That is, for example, localhost 9000 or 9999 slash m-x slash magit-status would run magit-status and show the magit-status buffer in the web browser. Or localhost 9000 slash m-x slash EWW slash any arbitrary URL to browse arbitrary URL with EWW inside of Firefox. It can serve as a way to block all JavaScript, because EWW does not support JavaScript. And Enforce preferred color scheming in Firefox, since HTMLize, as you have noticed, faithfully reflects the theme used in Emacs. Okay, so we know that YOLO is unsafe and needs to be refined. In fact, we don't necessarily want to run Emacs on a web browser. After all, a modern web browser is something one has to fight all the time and should be avoided whenever possible. We want to instead be able to access things when forced to be in a web browser, in which case only the motivations of an alternative frontend apply. Moreover, the ideal situation is an Emacs web framework, a tool that automatically transforms Emacs packages to web apps, so that one does not need to write extra code to get a web app that does the same thing as the package. We also need all links in the web pages to work. As noted before, the links on the YOLO Emacs splash screen do not work. So here's a proof-of-concept example. It's called bomb.el. It gets some weather forecast data from the Australian Bureau of Meteorology and displays it in an org buffer. So let's try it out. One could do mxbomb, which shows an org buffer with links to each state. So based in Melbourne, naturally, I would like to find out the weather of Victoria. And yes, to execute this command. Wait, wait, wait. Right. And we are at a buffer that shows the weather forecast of the whole of Victoria in the hierarchy. Note that this back button takes you to the previous page. So here are the regions of Victoria. I think Melbourne is in central. And yeah, it shows the seven-day weather forecast of Melbourne. You can also reach this page by running directly. Let's see. Directly bomb state. Vic. OK. So this works. And this is bomb as an Emacs package. Now let's check out bomb as a web app transformed by Emacs web framework. So start the web server with bomb start. And let's try it out. It's at 9000 again. Oops. Invalid path. Oh, that's because it makes exactly one command to one path. So remember that we used the BOM command to show the landing page. So here we need the BOM in the path as well. And it shows the same landing page, except in HTML. Let's check out Victoria weather forecast as before. And it shows an HTML converted from the org buffer using ox export HTML, whatever. And you can see even the back button is here. That takes you to slash bomb. So let's have a look at Melbourne. Here it is. Hooray, it works. So, yeah, as usual, you can stop the web server with bomb stop. Right. And alternatively, it can also be deployed directly in terminal in a dedicated Emacs daemon or Emacs daemon. So you can see that there's a one on correspondence between the Emacs package interface and the web interface. And that implies some restrictions to the Emacs package for the Emacs web framework to be able to do its job. Right. For example, the package needs to have an org interface and the links that trigger other commands need to be in Elixir links so that the Emacs web framework can translate it to web server URL path. Note that Emacs web server framework is not a real package. I wrote some functions in bomb.el serving the purpose, and they should be separated out eventually without much trouble. One could get weather forecast without running JavaScript anyway, which makes bomb.el less important as an alternative web client. Though it does provide, dare I say, clean and minimal interface compared to common weather forecast web pages. Other more relevant use cases could be mastodon, whose official web client requires JavaScript to display a post. The mastorg package that shows an org hierarchy of toots rooted as a given toot could be a low-hanging fruit. The limitation of org interface requirements can also be relaxed in further work. If one could extend Emacs web framework to translate back and forth between Emacs widgets, say, including buttons and web page widgets, including links. Another more far-fetched idea would be to translate to other types of interfaces, like Node slash Linux or an Android GUI. How about animations, say, Emacs butterfly, or even web games from Emacs games? Possibilities are limited in this, as always, in Emacs. I also noticed some limitations when trying to actually host bomb.el on the public web. Given the limited access to the Emacs server, I was comfortable enough to give bomb.el a go to serve it on the public web. However, I immediately stopped after noticing how slow it is. It can take more than 30 seconds to load a page of weather forecast for a stage. I am also not sure how many simultaneous connections it can handle. In any case, I think the packaged Emacs web server could do with some performance enhancement. Right. Because of the time constraints, I will briefly touch one final idea, which is to use Emacs as a Firefox browser extension. We already have Org Protocol, which allows Firefox to communicate with a running Emacs server by sending an Org Protocol URL to the latter. It can be used not just for capturing or storing links, but to execute arbitrary code on any component of the URL. However, it is fire and forget, and Emacs cannot tell Firefox what to do. There may be a length restriction, too. For example, Firefox may not be able to send back the whole DOM. This claim needs to be verified, though. Native messaging is one solution to this problem. It is a two-way communication channel between a Firefox web extension and a local system process started by the web extension. The process could be an Emacs server, which would make Emacs effectively a Firefox web browser extension. In this case, Elisp would be the main extension language, rather than JavaScript. However, JavaScript is still needed at the Firefox end of the communication channel. As a simple example of this idea, Firefox could ask Emacs to redirect a URL by removing tracking and using alternative frontend, etc. However, I was not able to implement this due to some tricky business with enforcing synchronicity that allows the web extension to wait for responses from Emacs. Some further work, I suppose. That concludes my talk. Thank you for your attention.