In some ways, we've taken a few steps back from a programmable web—two things I miss: bookmarklets and user scripts. Imagine having a bookmarked shortcut to do complex things like taking screenshots or saving a PDF. Or running scripts to automatically change the styling of websites, removing annoying sections (not just ads!). All of this used to be possible.
Brendan Eich, the author of JavaScript, thought that we'd use JavaScript bookmarklets to run arbitrary scripts against the DOM:
They were a deliberate feature in this sense: I invented the
javascript:
URL along with JavaScript in 1995, and intended thatjavascript:
URLs could be used as any other kind of URL, including being bookmark-able. In particular, I made it possible to generate a new document by loading, e.g.javascript:'hello, world'
, but also (key for bookmarklets) to run arbitrary script against the DOM of the current document, e.g.javascript:alert(document.links[0].href)
. The difference is that the latter kind of URL uses an expression that evaluates to the undefined type in JS. I added the void operator to JS before Netscape 2 shipped to make it easy to discard any non-undefined value in ajavascript:
URL. — Brendan Eich, email to Simon Willison
User scripts took this even further – Greasemonkey (and its successor Tampermonkey) – hosted a repository of scripts you could install and run on specific websites. These scripts added functionality to websites before companies could (or would) implement them – e.g., usability features for common sites like YouTube (add a download link), a queue for Netflix shows, or direct image links for Google Image Search.
Security policies have essentially killed the user script and bookmarklet ecosystem. Most of the scripts you can find on the remaining sites like Greasy Fork only provide minor improvements. The most-used scripts – like ad-blocking or annotating have become their own standalone browser extensions (e.g., AdBlock and Evernote/Notion Web Clipper).
The security benefit to consumers of blocking user scripts is probably a net positive for the average internet user. But why can't we have both? Surely we can find a way. Maybe running something like the QuickJS sandbox inside WebAssembly can provide a more secure way to access selective parts of the DOM.