Google Antigravity: The Complete Developer Guide (2026)
Google Antigravity applies real-time JavaScript physics to the Google homepage — elements float, collide, and drift. Complete 2026 guide: 11 verified fixes, six-layer architecture, Matter.js implementation, performance hacks, and security warnings.
In 2009, Ricardo Cabello — known as Mr. Doob — submitted a Chrome Experiment proving something no one had properly demonstrated: a browser could run a real-time rigid-body physics simulation without plugins, servers, or any infrastructure at all. Every element of the Google homepage fell, bounced, and collided using the same physics engine behind Angry Birds.
Google featured it in the Chrome Blog in 2012. It went globally viral. Dozens of regional forks appeared within months.
Seventeen years later, the experiment still runs. It still breaks in precisely the same ways it always has — and developers still debug it without understanding why it breaks. In March 2026, two new complications have entered the picture.
The first: the experiment's name now belongs to two products simultaneously. In November 2025, Google launched "Antigravity" — a fully separate agentic AI IDE built on VS Code with Gemini 3. Developers searching for one product now regularly land on documentation for the other, creating support dead ends that no article has resolved clearly until now.
The second: the fake mirror site ecosystem has become a genuine security hazard. Malicious actors have been creating Google Gravity clones that bundle the legitimate physics effect with credential stealers, crypto miners, and drive-by malware — and no mainstream coverage of the experiment warns about it.
This guide resolves both. For casual users: every reason Google Antigravity is broken in your browser in 2026, and exactly how to fix it. For developers: the complete six-layer architecture, the performance patterns separating a smooth 60fps experience from a CPU-pinning freeze, and a drop-in Matter.js implementation you can apply to any webpage today.
The Naming Problem: One Name, Two Products — A 2026 Disambiguation
This disambiguation must come first. In March 2026, searching "Google Antigravity" returns results for two completely unrelated products:
| Dimension | Google Anti-Gravity (Physics Experiment) | Google Antigravity (AI IDE) |
|---|---|---|
| Origin | Ricardo Cabello (Mr. Doob), 2009 | Google, November 2025 |
| What it is | Client-side DOM physics browser experiment | Agentic AI coding platform, VS Code + Gemini 3 |
| Where it runs | elgoog.im, mrdoob.com mirrors | antigravity.google |
| Official product? | No — third-party experiment | Yes — official Google developer product |
| Technology | Box2DJS / Matter.js physics engine | Gemini 3, VS Code fork, AI coding agent |
| Server dependency | None — fully client-side | Cloud-hosted AI inference |
| Who uses it | Casual users, browser experiment fans | Software developers, engineers |
If you are debugging the AI coding IDE — stop here. This article is exclusively about the 2009 browser physics experiment. The AI IDE has no connection to this codebase, this physics engine, or these mirror sites.
How Google Antigravity Works: The Complete Six-Layer Architecture
Understanding the full pipeline is the prerequisite for both effective debugging and building your own version. Every failure mode documented later in this article traces back to one specific layer.
Layer 1 — HTML Snapshot (Why Mirror Sites Exist)
Mirror sites (elgoog.im, mrdoob.com) serve a self-contained static HTML file designed to look like the Google homepage. All assets are inlined or base64-encoded within the file.
This architecture is not a workaround — it is a necessity. Live Google.com sends strict Content Security Policy headers blocking any script not explicitly whitelisted in its CSP policy. Injecting the physics script against live google.com will always be blocked. The experiment can only run against a static snapshot on a domain with permissive CSP headers.
This is why "Google Antigravity not working" is almost never a browser bug. It is CSP policy by design.
Layer 2 — DOM Traversal and Position Capture
At initialization, the physics script queries all major page elements using CSS selectors. It immediately captures each element's position using getBoundingClientRect() — returning a DOMRect with x, y, width, and height relative to the viewport. This position snapshot must happen before any CSS changes are applied, and all reads must be batched together to prevent premature layout reflows.
Layer 3 — Physics World Initialization
A physics world is created using Box2DJS (original version) or Matter.js (modern versions). Gravity direction and magnitude are configured here — this is the single value distinguishing Anti-Gravity (negative Y), standard Gravity (positive Y), and Zero Gravity (zero). Invisible static boundary bodies are created at all four viewport edges: floor, ceiling, left wall, right wall.
Layer 4 — DOM Detachment
Each element is removed from normal document flow by setting it to position: fixed anchored at a zero origin, with transform handling all positioning. Parent container positioning is flattened to prevent stacking context interference. From this point, the element's visual position is owned entirely by the physics engine — not the browser's layout system.
Layer 5 — The Render Loop
requestAnimationFrame drives a loop at up to 60fps. Each frame executes exactly two operations: step the physics world forward by one timestep (updating all body positions and rotation angles), then read each body's new position and write it to the corresponding DOM element's CSS transform property. This two-step pattern is the complete mechanism.
Layer 6 — Input Handling
Mouse and pointer events are translated into physics forces. On pointerdown, the element under the cursor is identified and its physics body is attached to a spring constraint between the body and cursor position — a "mouse joint." Moving the cursor drags the body via spring force. On pointerup, the spring releases and the body's current velocity carries it forward.
The Gravity Variants: One Architecture, Four Behaviors
All four major variants share the same six-layer architecture. The entire behavioral difference is a single vector value in Layer 3:
In Matter.js, activating anti-gravity requires changing one line: engine.gravity.y = -1. Every other architectural element remains identical.
11 Hacks: Root Causes and Verified Fixes
Hack 1 — Script Does Nothing: Page Loads Normally, No Physics
Root Cause: JavaScript is disabled, or a script-blocking extension is silently preventing execution. The entire effect is JavaScript-driven from initialization to render loop. Without it, the page loads without error and without physics — and no visible indication is shown.
Fix — ordered by likelihood:
Step 1: Test in private/incognito mode first. Extensions are disabled by default in incognito. If the physics works there, an extension in your normal session is blocking it.
Step 2: Verify JavaScript is enabled in your browser:
Chrome: Settings → Privacy and Security → Site Settings → JavaScript → Allow
Firefox: about:config → javascript.enabled → must be true
Safari: Preferences → Security → Enable JavaScript
Step 3: Open DevTools (F12) → Console tab. Red text reading "Refused to execute script" or any CSP-related message means you are attempting to run the script against live google.com. This will always fail. Use a mirror site.
Step 4: Disable extensions one at a time to identify the blocker. Primary suspects: uBlock Origin (hard mode), NoScript, Privacy Badger, Ghostery. These tools frequently flag the Box2D or Matter.js libraries as third-party trackers and drop them silently.
Hack 2 — No Effect on Mobile: Broken or Garbled Layout
Root Cause: The original mrdoob.com version was built exclusively for desktop in 2009. It uses mousedown, mousemove, and mouseup events with zero touch event fallbacks. The physics coordinate math is hardcoded around fixed-pixel desktop viewport assumptions. Mobile viewports break the initial body placement math, and touch interactions do not register at all.
Fix:
Step 1: Do not use the original mrdoob.com version on mobile. The source has never been updated for touch support. It will always be broken on mobile.
Step 2: Use elgoog.im/gravity/ directly. This mirror has been rebuilt using the Pointer Events API, which handles mouse, touch, and stylus input uniformly with a single event model.
Step 3: For custom implementations, replace all mouse listeners with Pointer Events:
Step 4: For iOS Safari specifically, add { passive: true } to all pointer listeners to prevent scroll-blocking warnings that can prevent events from firing:
Hack 3 — Extreme Lag, Browser Freeze, Fan Spinning Immediately
Root Cause: This is the most technically significant failure mode across all older forks and custom implementations. The physics engine updates element positions 60 times per second. Older implementations write to element.style.left and element.style.top. These two CSS properties trigger a full layout recalculation — the browser must recompute the geometry of every element on the page per frame. This is called layout thrashing.
When getBoundingClientRect() reads are interleaved with style writes within the same frame, the browser is forced to flush its pending layout queue repeatedly, multiplying the per-frame cost further.
What old forks do wrong:
The correct approach — GPU compositor, zero layout cost:
CSS transform bypasses the layout engine entirely. The GPU compositor thread handles it independently of the main thread. Measured performance difference: 5–10× faster on pages with many elements.
Step 1: Verify hardware acceleration is enabled. In Chrome: navigate to chrome://gpu → confirm "Hardware accelerated" appears next to Canvas 2D, WebGL, and Compositing. If showing "Software only": Settings → System → Use hardware acceleration → toggle on → relaunch browser.
Step 2: Use elgoog.im. It uses the correct transform approach. Most third-party forks from 2012–2018 still use top/left and will always perform poorly.
Hack 4 — Search Bar Produces No Results
Root Cause: The original physics script connected to Google's Web Search API to fetch and display real search results. Google permanently deprecated and shut down this API in 2014. The physics simulation itself is completely functional — only the data pipeline is broken. Mirror sites attempt API emulation but may fail due to CORS restrictions, outdated credentials, or rate limiting.
Fix:
Step 1: Use elgoog.im — it maintains the most current search emulation layer.
Step 2: For custom implementations, the search bar is a fully functional HTML <input> element. Redirect form submissions to Google Search directly:
Hack 5 — Elements Start in Wrong Positions or Partially Off-Screen
Root Cause: A race condition between physics initialization and the page completing its final layout render. The script captures element positions using getBoundingClientRect() at startup. If web fonts, lazy-loading images, or async stylesheets have not finished loading at that exact moment, the captured positions are stale or zero. Physics bodies are then placed at incorrect coordinates that do not match the visual element positions.
Fix:
Step 1: Switch initialization from DOMContentLoaded to window load:
Step 2: If web fonts specifically are the cause, use document.fonts.ready:
Step 3: As a hard fallback — add a 300–500ms delay after the load event to allow all reflows from late-loading resources to fully settle before capturing positions.
Hack 6 — CSP Blocks Script Execution Against Live Google.com
Root Cause: Modern Google.com sends strict Content Security Policy headers that block any script not explicitly whitelisted. The browser console shows: "Refused to execute inline script because it violates the following Content Security Policy directive." This is architecture — not a bug.
Fix:
Step 1: Do not attempt to run physics scripts against live google.com. It is not technically possible without a browser extension overriding CSP headers. No amount of configuration will change this.
Step 2: Use mirror sites (elgoog.im) that host their own static Google UI snapshot with permissive or absent CSP headers on their own domain.
Hack 7 — Elements Escape Through Walls After Browser Resize
Root Cause: The invisible boundary walls (floor, ceiling, left wall, right wall) are static physics bodies created once at initialization using the viewport dimensions at that exact moment. When the browser window is resized, the visual boundary moves — but the physics bodies remain at their original coordinates. Elements then pass through the gap between the old physics wall position and the actual new screen edge.
Fix:
Hack 8 — Elements Tunnel Through Walls at High Speed
Root Cause: Classic discrete physics simulation tunneling. The engine steps forward in 1/60th-second increments per frame. If an element moves farther than its own width or height within a single step, collision detection checks positions before and after the step — but never detects the overlap that existed mid-step. The element passes straight through the wall.
Fix — Box2D approach: Enable Continuous Collision Detection on fast-moving bodies:
Fix — Matter.js approach: Cap maximum velocity in the beforeUpdate event:
Hack 9 — iframe Embedding: Mouse Coordinates Are Offset
Root Cause: Inside an iframe, event.clientX and event.clientY are relative to the iframe's own viewport origin — not the parent page. If the iframe is embedded at an offset position within the parent page, dragging physics elements appears to lag behind the cursor by exactly that offset distance.
Fix:
Hack 10 — Browser Extension Interference: Partial Elements Missing
Root Cause: Ad blockers match DOM elements against known ad unit signatures by size, class name, or position. Some Google homepage elements match these signatures and are silently removed from the DOM before the physics script runs. The script attempts to create physics bodies for missing elements, encounters null references, throws a JavaScript error, and in many implementations aborts the entire physics initialization.
Fix:
Step 1: Test in incognito mode to confirm whether extensions are responsible.
Step 2: Always null-check and filter removed elements before body creation:
Step 3: Wrap each body creation in try/catch to prevent a single missing element from aborting the full initialization:
Hack 11 — HTTPS Mixed-Content Warning Blocks Physics Library
Root Cause: Older forks reference Box2D.js and other libraries via http:// CDN URLs. Modern browsers block mixed active content — any script loaded over HTTP on an HTTPS page is silently blocked. The physics library fails to load, the global Box2D or Matter object is undefined, and the initialization script crashes immediately with a ReferenceError.
Fix:
The permanent solution is to self-host all physics libraries. This eliminates CDN dependency, mixed-content risk, Subresource Integrity maintenance, and third-party tracking simultaneously.
Physics Engine Deep Dive: Box2D vs Matter.js
Box2DJS (Original 2009 Engine)
Box2DJS is a direct JavaScript port of Erin Catto's Box2D C++ library — the same engine behind Angry Birds. It uses AABB (Axis-Aligned Bounding Box) broad-phase collision detection and an iterative constraint solver.
Critical developer notes that trip up most implementations:
Shapes use extents (half-width, half-height from center), not full dimensions. A 200×50px element requires extents.Set(100, 25). Developers expecting full-dimension APIs will offset every physics body.
Pixel coordinates must be divided by a world scale factor (typically 30) before passing to Box2D, then multiplied back by 30 for rendering. Box2D is calibrated for real-world meter units:
Matter.js (2026 Standard)
Matter.js is the correct choice for any new DOM physics implementation in 2026. It works natively in pixel coordinates, provides a significantly cleaner API, and performs better at high body counts through optimized broad-phase spatial hashing.
Physics Material Reference — All Five Presets
frictionAir is the most impactful value for the anti-gravity variant — higher values cause elements to drift gently to rest rather than floating indefinitely.
Professional Workflow System: The PHYSICS Method
A proprietary six-phase implementation framework for deploying DOM physics on any webpage from zero to production-ready.
PHYSICS: Prepare → Hook → Initialize → Simulate → Control → Secure
Phase 1: Prepare — Position Capture Without Layout Thrashing
The single most important implementation decision is capturing all element positions before making any DOM changes. The wrong pattern — interleaving reads and writes — forces the browser to flush its layout queue per element:
Setting left: 0 and top: 0 then using transform for position is deliberate. It anchors each element at a fixed origin and delegates all actual positioning to the GPU compositor — the same pattern used by GSAP and all high-performance animation libraries.
Phase 2: Hook — Boundary Wall Construction With Resize Safety
Phase 3: Initialize — Physics Bodies from DOM Elements
Phase 4: Simulate — The Render Loop With Center-to-Corner Correction
The center-to-corner physics offset is the most frequently missed implementation detail. Physics engines track body position by center point. CSS positions elements from their top-left corner. Without subtracting half-dimensions, every element appears visually offset by exactly half its size in both dimensions:
Phase 5: Control — Runtime Gravity Switching and DeviceMotion
Runtime gravity direction — no world reset required:
Continuously rotating gravity — perpetual tumbling wheel effect:
DeviceMotion tilt control — physical device tilt becomes gravity direction (iOS 13+ requires permission via explicit user gesture):
Phase 6: Secure — Production Safety and Accessibility Checklist
1. Check prefers-reduced-motion before any initialization:
Users with vestibular disorders, epilepsy, or motion sensitivity can experience genuine physical discomfort from animated physics simulations. This check is non-negotiable for any production deployment.
2. Opt-out attribute for navigation and critical elements:
Never apply physics to navigation, form elements, error messages, or primary calls-to-action.
3. Complete physics reset for accessibility:
Always provide a keyboard-accessible reset button that remains focusable and visible even while elements are floating.
4. FPS monitoring with graceful degradation:
5. Subresource Integrity for CDN dependencies: The definitive solution: self-host all physics libraries. Eliminates CDN dependency, mixed-content risk, and SRI maintenance in one step.
Performance Optimization: Ranked by Verified Impact
Hidden Features and Undocumented Behaviors
Search still works when physically buried. Even when the search bar is rotated 180 degrees, buried under the Google logo, or pushed to a corner by collisions, it remains a fully functional HTML <input>. The clickable area follows the physics transform exactly. The physics layer is purely visual — the DOM structure and all event handlers remain intact underneath.
DeviceMotion tilt gravity on MacBook and iOS. Documented in a 2013 Hacker News thread: MacBook Pros with Sudden Motion Sensors expose physical tilt data via the DeviceMotionEvent API. Certain forks respond to literally tilting the hardware — the laptop becomes a physics controller. Requires HTTPS and an explicit user-gesture permission request in modern Chrome and Safari.
Search results physically fall (mirror-specific). On mirror sites with restored search functionality, submitting a query causes result cards to materialize at the top of the viewport and fall into the existing pile, colliding with the floating logo and buttons. This feature was added by mirror developers — it does not exist in the original mrdoob.com version.
Mouse repulsion field (Space variant). In the Zero-Gravity variant, the cursor emits a continuous repulsion force. Moving near elements pushes them away without clicking — implemented by applying outward forces each frame proportional to the inverse square of the cursor-to-body distance.
Body sleeping and wake cascades. Both Box2D and Matter.js implement body sleeping — resting bodies are excluded from all simulation calculations, velocity set to zero, and skipped during the physics step. The cascade is visible: throw one element into a settled pile and watch the collision wake dormant bodies in a chain reaction.
Advanced Extensions
Explosion / Radial Impulse on Double-Click
Gravity Well / Black Hole Attractor
Mouse Repulsion Field (Space Variant Recreation)
Browser Compatibility Reference (March 2026)
Mistakes Most Developers Make in 2026
Running physics scripts against live google.com. Content Security Policy on google.com will block every injected script without exception. This is not a bug, a browser setting, or an extension conflict. It is an architectural security policy. No debugging, no tool, and no workaround will change this. Use a mirror site.
Initializing on DOMContentLoaded instead of window.load. DOMContentLoaded fires before web fonts and images have finished loading. getBoundingClientRect() captures positions before the final render is complete. Every element appears offset by the height of content that loads after initialization. Switch to window.addEventListener('load', ...) — always.
Using top and left instead of transform for position updates. This is the single most common cause of browser freeze in older forks and custom implementations in 2026. Writing style.top and style.left at 60fps triggers full layout recalculation per frame. Using transform runs on the GPU compositor with zero layout cost. The performance difference is 5–10× and is immediately measurable via Chrome DevTools Performance tab.
Not removing old boundary walls on resize. Adding new walls without removing old ones creates invisible duplicate collision surfaces inside the viewport. Elements begin bouncing off nothing, passing through visible walls, and behaving erratically. Always call World.remove on old walls before World.add with new ones.
Missing the center-to-corner physics offset. Physics engines track body position by center point. CSS positions from the top-left corner. Without subtracting body._halfW and body._halfH from the transform coordinates, every element appears shifted diagonally. The error is invisible in simple test pages and catastrophic in production.
Not null-checking before body creation. Ad blockers remove DOM elements before physics initialization. Attempting to create physics bodies for removed elements causes null reference errors that abort the entire initialization sequence. Always filter by el.offsetParent !== null before processing any element.
Trusting any Google Gravity mirror site beyond known safe domains. Fake mirror sites bundling credential-stealing scripts or cryptocurrency miners with the physics effect are an active threat in 2026. Safe domains: elgoog.im/gravity/ and mrdoob.com. Red flags for malicious mirrors: any login prompt, camera or microphone permission requests, service worker installation, or unusually slow load times.
Skipping prefers-reduced-motion in production. This is an accessibility requirement, not a suggestion. Users with vestibular disorders experience genuine physical discomfort from physics animations. Check window.matchMedia('(prefers-reduced-motion: reduce)') before any initialization. Skip the physics entirely if this media query returns true.
Strategic Conclusion
Google Antigravity — the 2009 browser physics experiment — has outlasted the infrastructure it was built on, the browser paradigms it demonstrated, and the original hosting that ran it. It continues to run in March 2026 because the underlying six-layer architecture is sound: position capture, physics world, DOM detachment, GPU-composited render loop, input handling. Those principles have not aged.
The failure modes documented in this article are not new bugs. They are the same architectural mismatches that have caused the same failures across every fork for seventeen years — layout thrashing from top/left writes, position race conditions from DOMContentLoaded timing, element escape from static boundary walls on resize, and coordinate offset from the center-to-corner physics mismatch. Each is fixable with exactly one code change.
Three new complications define the landscape in March 2026. The naming collision with Google's AI IDE creates search confusion that must be resolved with disambiguation before anything else. The fake mirror site security threat is active and documented. And the experiment's performance patterns — batched reads, GPU-composited transforms, body sleeping — are now directly applicable to production animation, interactive landing pages, and game-like web experiences that extend far beyond the original Google homepage context.
The PHYSICS Method framework in this article represents the current best practice for DOM physics in 2026. The performance optimizations are ranked by verified impact, not convention. The security checklist is non-negotiable for production use.
For casual users: elgoog.im. Nowhere else.
For developers: transform, not top/left. window.load, not DOMContentLoaded. Center minus half-dimension, not center alone. These three corrections fix the majority of all DOM physics implementations that have ever shipped broken.
Frequently Asked Questions
Common questions about this topic
