Skip to content

Repository files navigation

A black hole eats an encyclopedia page: letters tear off and spiral into a glowing accretion disk, a second hole bends the photo with its gravity, the two merge, then a white hole puts every letter back.

SINGULARITY

A black hole that eats any website.

Click anywhere on a page. Letters tear off one by one, spiral into a glowing accretion disk
and fall past the event horizon. Press Esc and a white hole puts every letter back.

Try it now  ·  Install  ·  Controls  ·  How it works

MIT license zero dependencies 61 KB minified no tracking


What it does

Singularity turns the page you are reading into food for a black hole, and then gives it back.

  • Tidal disruption. Letters near the hole are lifted off one by one and redrawn as particles in the page's own font and colour. The paragraph around them does not move, so the hole leaves clean gaps.
  • Accretion. Particles settle into orbit, stretch along their path and heat from ember red to blue-white before they cross the event horizon. The page bends around the hole through real gravitational lensing.
  • Growth. The hole gains mass from everything it swallows. A young hole manages letters and icons. A grown one tears whole images, buttons and cards off the page and shatters them like glass.
  • Mergers. Throw one hole into another. They spiral in, merge with a chirp, and radiate a gravitational wave that rips letters off along its front.
  • Collapse. Press Enter: every hole falls to the centre and eats the screen. You get a card with the totals to save and post.
  • White hole. Press Esc: time runs backwards and every letter flies home. The page was never rewritten, so it comes back pixel-identical.

The counter in the corner shows tokens ingested: one token for every four characters swallowed, plus images by area (width × height / 750, the way vision models count them). Background images count at half that rate.

Install

Pick whichever fits. All four run the same single file.

1. Bookmarklet (Chrome, Edge, Safari, Firefox, Arc, Brave)

  1. Open the demo page.
  2. Drag the black Singularity button into your bookmarks bar. No bar? Ctrl+Shift+B, or ⌘+Shift+B on a Mac.
  3. Open any website and click the bookmark. Click it again (or press Esc) to put the page back.

GitHub can't render javascript: links in a README, so the button lives on the demo page. To create the bookmark by hand, make a new bookmark and paste the contents of bookmarklet.txt as its URL. The whole engine is inside the bookmark (about 62,000 characters, under Firefox's 65,536 limit), so it also works on sites with a strict Content Security Policy.

2. Chrome extension (Chrome, Edge, Brave, Arc)

  1. Download this repository (Code → Download ZIP) and unzip it.
  2. Open chrome://extensions and switch on Developer mode.
  3. Click Load unpacked and pick the extension folder.
  4. Click the black hole icon on any page, or press Alt+Shift+S. Press it again to put the page back. You can change the shortcut at chrome://extensions/shortcuts.

3. Console

Open DevTools on any page, paste the contents of singularity.min.js into the console and press Enter. Chrome and Firefox may ask you to type allow pasting first.

4. Userscript

With Tampermonkey or Violentmonkey installed, open the raw userscript and confirm the install. Then press Alt+S on any page, and again to put the page back.

Controls

Input What it does
Click Open a black hole where you clicked (up to seven)
Drag a hole Move it. Let go while moving to throw it
Drag onto another hole Merge the two. The bigger one keeps its spin
Enter Collapse everything into one hole and get the result card
Esc White hole: restore the page and switch Singularity off
R Restore the page and keep playing
A Autopilot: the hole wanders and eats its way down the page (made for screen recordings)
H Hide or show the panel
M Sound on or off
P Pause
S Save the result card as a PNG (on the card)
Phone Tap to open a hole, drag a hole to move it, scroll as usual

How it works

Singularity is one dependency-free script (src/singularity.js, about 61 KB minified). A few details that make it work on real sites:

  • No DOM rewrites. Torn letters are hidden with the CSS Custom Highlight API: each eaten run of characters becomes a Range in a highlight whose colour is transparent. Text nodes are never split or wrapped, so React, Vue and other frameworks keep running underneath and nothing reflows.
  • Finding food. Each frame the engine probes points inside every hole's reach with document.elementsFromPoint, then measures characters with Range.getBoundingClientRect. Fixed headers, sticky bars, scroll containers and open shadow roots are handled for free.
  • Disk physics in polar coordinates. Particles carry radial and orbital speeds around their hole plus a carrier velocity that lags behind it, which is why a thrown hole drags a smeared disk. Integrating in polar form avoids the fake centrifugal drift of naive Euler steps.
  • Rendering. A full-resolution canvas draws glyphs bucketed by font, first in their own colour, then additively as they heat up. A half-resolution glow layer with persistent trails and mix-blend-mode: screen gives the plasma, which also means it only shows where the page is dark.
  • Gravitational lensing. Each hole carries a backdrop-filter that points at an SVG feDisplacementMap, swirling and pulling the page around it (Chromium). Other browsers get the darkness without the bend.
  • Images and blocks. Pictures, video frames and canvases are cut into textured triangles that keep the image's CSS filter. Icons, backgrounds and borders of buttons and cards become tiles in their own colours. Elements the hole is not yet big enough to eat lean towards it through the translate and rotate properties. Password fields only ever show dots.
  • White hole. Every eaten character is logged with its live Range, so on Esc each letter flies to where it is now, even if the page scrolled or reflowed. Inline styles are restored to their exact previous values.
  • Strict CSP friendly. No eval, no innerHTML, no remote code. Styles go through CSSOM and constructed stylesheets. Sound is synthesized with Web Audio.

Browser support

Browser Status
Chrome, Edge, Brave, Arc 105+ Everything, including lensing
Safari 17.2+ Everything except lensing
Firefox 140+ Everything except lensing
Older browsers Works, but hides whole text nodes at once instead of single letters

Privacy

No analytics, no storage, no servers: the script never sends anything anywhere. The only things it loads are the page's own background images, usually straight from the browser cache. Everything happens in your tab and is gone when you press Esc or reload. The demo site loads no third-party scripts or fonts.

Development

npm install          # terser for the build, playwright for the tests
npm run build        # src/singularity.js -> singularity.min.js, bookmarklet.txt, extension/, userscript/
npm test             # headless smoke test: eat, merge, collapse, white hole, compare markup and pixels
npm run demo         # renders demo.mp4, assets/demo.webp and assets/demo.gif frame by frame (needs ffmpeg)

Once it runs, the engine exposes a small API on window.__singularity:

Call Does
addHole(x, y) Open a hole at viewport coordinates
collapse() Same as Enter
restore() White hole, keep running (same as R)
toggle() White hole and switch off (same as Esc)
stop() Restore instantly and switch off, no animation
autopilot() Same as A
stats() Tokens, images, merges, particle count and phase

Options can be set before the script loads through window.__SG_OPTIONS, for example { sound: false, hud: false, autostart: false, at: { x: 200, y: 300 } }. Setting window.__SG_MANUAL = true stops the animation loop so tests can drive frames with step(dt).

singularity/
├── index.html            demo page (GitHub Pages)
├── singularity.min.js    built engine
├── bookmarklet.txt       built bookmarklet
├── src/singularity.js    readable source
├── extension/            Chrome extension (Manifest V3)
├── userscript/           Tampermonkey / Violentmonkey script
├── scripts/              build and demo recorder
├── test/                 smoke test and a fixture page
└── assets/               demo media, plate images, icon, fonts

License

MIT © 2026 shmidt. Made by @shmidtqq. Fonts in assets/fonts are under the SIL Open Font License.

If you feed something good to it, post the card and tag me.

Releases

Packages

Contributors

Languages