Tab Haunting Extension– Ghosts of Closed Tabs

Haunt your browser with ghostly reminders of closed tabs. A fun extension that brings your browsing history back to life.
Find Me: Google Knowledge Panel
Common Questions about ExtensionHub.app: More
We independently provide precision extensions, and expert resources for browser extension. Learn More.
Lightweight closed-tab recovery Browser Extension
Free
⬇️ Available on Chrome · Edge · Firefox

👻

Tab Haunting Chrome Extension — Complete User Guide

How every ghost appears, what triggers it, and how the formulas behind it actually work.

Chrome Extension · Manifest V3 · Free

What Is Tab Haunting and What Does It Calculate?

Tab Haunting is a humor-first browser productivity extension for Google Chrome. Every time you close a browser tab, the extension quietly records how long you spent on it, what kind of page it was, and how important it appeared. A short time later — anywhere from 30 seconds to several hours, depending on your settings — a semi-transparent ghost overlay floats onto your current active tab, delivering a personality-matched guilt message on behalf of the tab you abandoned.

Unlike a basic tab history tool, Tab Haunting calculates four separate outputs in real time: the ghost's priority tier, the scheduled haunting time, the personality selection probability, and your running Guilt Score. Each of these is derived from a defined formula explained in detail below.

Where This Extension Gets Used

  • Remote workers who open dozens of research tabs during a session and frequently regret closing them mid-read.
  • Developers who close Stack Overflow tabs before implementing the fix they found.
  • Online shoppers who dismiss product pages only to want them back hours later.
  • Students and researchers who open academic links, skim the abstract, and close before reading the conclusion.
  • Productivity enthusiasts who want a light-hearted audit of their own browsing habits.

Key User Pain Points and How Tab Haunting Solves Them

⚠ Problem

You close a tab and immediately regret it. Chrome's native Ctrl+Shift+T requires you to remember you had it.

✓ Solution

Tab Haunting pushes the memory to you. The ghost appears unprompted, recovering your attention without any manual action.

⚠ Problem

You spent 12 minutes reading a tutorial, closed it, and can no longer find it in your history because you opened 40 more tabs since.

✓ Solution

The Ghost Graveyard stores every closed tab with its URL, title, and time-on-tab. Searchable and exportable to CSV.

⚠ Problem

Generic "tab manager" tools are boring and add friction. You never actually use them.

✓ Solution

Tab Haunting uses humor and personality to make the experience memorable. The guilt message system means you engage with it rather than ignoring it.

⚠ Problem

You have no visibility into your own tab-closing behavior — how many tabs you close, how quickly, and which domains you abandon most.

✓ Solution

The Guilt Score dashboard quantifies your tab habits with a live score, weekly summary, and most-haunted domain leaderboard.

Ghost Creation Flow — How the Extension Works Step by Step

The diagram below shows the complete lifecycle of a single ghost, from the moment you close a tab to the moment the overlay appears on your screen. Each box maps to a formula or decision point explained in the sections that follow.

Formula 1 — Time on Tab Calculation

Every time Chrome creates a new tab, the extension records the exact timestamp in milliseconds. When the tab closes, it calculates the session duration using the following formula:

Formula: Time on Tab timeOnTab = Math.floor( (closedAt − openedAt) ÷ 1000 )
Where:
closedAt = timestamp when tab was removed [ms] openedAt = timestamp when tab finished loading [ms] Result = duration in whole seconds [s]

Units: Input timestamps are in milliseconds (ms) from Date.now(). The result is expressed in seconds (s) after integer division by 1,000. Math.floor() ensures no partial seconds are counted — a tab open for 59.9 seconds counts as 59, not 60.

⚠ Common Mistake: Ghost Never Appears for Tabs You Open Briefly

If you open a tab and close it in under 10 seconds (the default minTimeOnTab threshold), the extension intentionally skips haunting. This prevents ghost spam from accidental opens or redirects. If a ghost isn't appearing, check Settings → Timing and lower the "Minimum time on tab" value.

Formula 2 — Ghost Priority Tier Classification

Once the time on tab is known, the extension classifies each ghost into one of three priority tiers. The tier controls which message pool is drawn from and how urgently the ghost behaves. Title keywords also influence the tier — tabs with words like "tutorial," "guide," or "how to" are automatically elevated to High priority regardless of time.

Formula: Ghost Priority Tier IF timeOnTab < 5 → priority = "petty" ELSE IF timeOnTab > 300 → priority = "high" ELSE IF title contains keyword → priority = "high" ELSE → priority = "normal"
Regret keywords: tutorial, how to, best, guide, review, vs
Priority Tier Trigger Condition Time on Tab Message Pool Used
Petty 😤 Tab closed in under 5 seconds 0–4 s Short, snarky messages ("Opened for 3 seconds. Classic.")
Normal 😑 Standard close, no keyword match 5–300 s Standard personality message pool
High 🕯️ 5+ minutes on tab, or title contains regret keyword > 300 s Priority messages with stronger guilt language

💡 Microcopy — Why Keywords Matter

Titles containing "tutorial," "how to," "guide," "best," "review," or " vs " are treated as high-priority regardless of how long you spent on them. This is intentional — a tutorial you glanced at for 20 seconds is exactly the kind of tab you'll regret. The extension flags it before you forget it existed.

Formula 3 — Weighted Random Personality Selection

The extension ships with 10 ghost personalities, each assigned a configurable weight in Settings → Personalities. Rather than pure random selection, it uses weighted random sampling — personalities with higher weights appear proportionally more often.

Formula: Weighted Personality Picker totalWeight = Σ (all personality weights) r = Math.random() × totalWeight // uniform random float in [0, totalWeight)
FOR each personality (id, weight) in order:
r = r − weight IF r ≤ 0 → return this personality
Fallback: return first personality in list

Worked Example: Personality Probability with Default Weights

With default settings the total weight sum is 100. The probability of each personality appearing is its weight as a direct percentage:

Personality Emoji Default Weight Probability Sample Message
Guilt Tripper🕯️2525%"You spent 4m 12s on me and then just... left."
Passive Aggressive😑2020%"No no, go ahead. Do whatever you were doing."
Scholar📚1515%"The answer was in my third paragraph."
Dramatic😭1010%"I HAD THE ANSWER. You will NEVER know."
Zen🧘1010%"I was a tab. Now I am free. Are you?"
Shopper🛍️55%"That sale ended at midnight. I hope it was worth it."
Nerd🤓55%"Error 404: Your attention not found."
Whiner👶55%"You didn't even scroll down to the good part."
Karen😤33%"I would like to speak to your bookmarks manager."
Melancholic🌙22%"I remember when you opened me with such hope."

Weights do not need to sum to 100. The algorithm works with any total — a weight of 5 is always twice as likely as a weight of 2.5, regardless of what all other weights sum to.

🕯️Guilt Tripper"You spent {time} on me and then just... left."
😑Passive Aggressive"It's fine. I'm fine. We're all fine."
📚Scholar"I was a peer-reviewed article. You'll never know."
😭Dramatic"You closed me mid-sentence. MID. SENTENCE."
🧘Zen"The URL does not define me. Neither does your history."
🛍️Shopper"The price went up. I watched it happen."
🤓Nerd"Have you tried focusing?"
👶Whiner"The comments were good. You missed the comments."
😤Karen"I'm filing a complaint with your browser history."
🌙Melancholic"It was {time} ago. Feels like forever now."

Formula 4 — Ghost Schedule Time (Randomised Delay)

To avoid predictability — and to heighten the dramatic effect of the ghost appearing when you've least expected it — the haunting time is randomised within your configured delay window.

Formula: Scheduled Haunting Time minMs = minDelay × 1000 // convert seconds → milliseconds maxMs = maxDelay × 1000 // convert seconds → milliseconds delay = minMs + Math.random() × (maxMs − minMs) scheduledAt = Date.now() + delay // absolute Unix ms timestamp
Setting Default Value Unit Valid Range Effect
minDelay 30 seconds 0 – 86,400 Earliest a ghost can appear after tab close
maxDelay 1,800 (30 min) seconds 0 – 604,800 (7 days) Latest a ghost can appear after tab close
maxPerHour 3 count / hr 1 – 20 Hard cap on ghost appearances per clock-hour
minTimeOnTab 10 seconds 0 – 600 Tabs open for less than this are not haunted

⚠ Common Mistake: Setting maxDelay Too High

If you set maxDelay to 7 days and close hundreds of tabs, you will accumulate a large ghost queue that fires unpredictably days later. Keep maxDelay under 2 hours for a satisfying experience where ghosts feel timely and relevant.

Formula 5 — Quiet Hours Boundary Detection

When an alarm fires during quiet hours, the ghost is not shown — it is rescheduled 30 minutes later automatically. The quiet hours check handles midnight crossover correctly:

Formula: Is Current Time in Quiet Hours? nowMinutes = currentHour × 60 + currentMinute // minutes since midnight startMinutes = startHour × 60 + startMinute endMinutes = endHour × 60 + endMinute
IF startMinutes < endMinutes: // same day (e.g. 09:00 – 17:00)
return nowMinutes ≥ startMinutes AND nowMinutes < endMinutes ELSE: // crosses midnight (e.g. 23:00 – 07:00) return nowMinutes ≥ startMinutes OR nowMinutes < endMinutes

Example with default settings (23:00 – 07:00): At 02:30 AM, nowMinutes = 150, startMinutes = 1380, endMinutes = 420. Since startMinutes > endMinutes (crosses midnight), the second branch applies: 150 ≥ 1380 is false, but 150 < 420 is true → quiet hours are active, ghost is rescheduled.

Formula 6 — The Guilt Score Calculation

The Guilt Score is a running metric displayed in the extension popup. It reflects both the volume of tabs you close and how ruthlessly you exorcise ghosts (treating exorcisms as a more "cold-blooded" act worth double the score contribution).

Formula: Guilt Score rawScore = (totalClosed × 0.05) + (totalExorcisms × 2) score = Math.min(100, Math.round(rawScore)) // capped at 100
Guilt Tier mapping:
score 0–25 → "Low Guilt" score 26–50 → "Mild Regret" score 51–75 → "Haunted Soul" score 76–100 → "Tab Murderer 💀"

Guilt Score Tier Visualisation

Low Guilt
0–25
Mild Regret
26–50
Haunted Soul
51–75
Tab Murderer 💀
76–100

Closing 200 tabs with 0 exorcisms = score of 10 (Low Guilt). Closing 200 tabs and exorcising 40 ghosts = score of 90 (Tab Murderer).

Worked Example: Calculating Your Guilt Score

Scenario: End of a Heavy Research Session

1You close 340 tabs over the course of a week.
2Of the ghosts that appeared, you permanently exorcised 18 (those URLs you never wanted to see again).
3Apply the formula: rawScore = (340 × 0.05) + (18 × 2) = 17 + 36 = 53
4score = Math.min(100, Math.round(53)) = 53
Result: Score 53 → Haunted Soul. You close a lot of tabs and you're not afraid to banish them. The ghosts respect that, begrudgingly.

Formula 7 — Dynamic Message Variable Substitution

Ghost messages use live metadata variables that are substituted at render time. This is what makes messages feel eerily personal rather than generic.

Variable Substitution Rules {time} → formatDuration(timeOnTab) = timeOnTab < 60 ? "${secs}s" timeOnTab ≥ 60 ? "${mins}m ${secs}s"
Domain override (takes priority over personality pool):
reddit.com → fixed message stackoverflow.com → fixed message youtube.com → fixed message amazon.com → fixed message github.com → fixed message

Example substitution: A tab open for 267 seconds on the Scholar personality would produce: "I contained the tutorial you needed 4m 27s ago."

Full End-to-End Worked Example

This walkthrough applies every formula to a single real-world scenario so you can see exactly what the extension calculates from start to finish.

Scenario: A developer closes a Stack Overflow tab

1 Tab opened at 14:22:10 (openedAt = 1700000530000 ms). Page is a Stack Overflow answer titled "Best way to debounce in JavaScript."
2 Tab closed at 14:27:53 (closedAt = 1700000873000 ms).
3 Time on tab: Math.floor((1700000873000 − 1700000530000) ÷ 1000) = Math.floor(343000 ÷ 1000) = 343 seconds (5 min 43 sec)
4 Priority: 343 > 300 → "high". Also confirmed by title containing "best" — doubly elevated.
5 Domain override check: domain = stackoverflow.com → fixed message: "The accepted answer was right there. Right. There." (overrides personality pool)
6 Schedule: With minDelay = 30s, maxDelay = 1800s, Math.random() = 0.44:
delay = 30000 + 0.44 × (1800000 − 30000) = 30000 + 778800 = 808800 ms ≈ 13.5 minutes
7 Time check: 14:41 is not in quiet hours (23:00–07:00) → ghost is cleared to appear.
👻 At 14:41, while the developer is on a different page, the ghost overlay appears with the Stack Overflow favicon, the title, and the message: "The accepted answer was right there. Right. There." The developer clicks "Visit Again" and reopens the tab to actually implement the fix.

Common Mistakes When Using Tab Haunting

Mistake Why It Happens How to Fix It
No ghosts ever appear All closed tabs are below the minTimeOnTab threshold, or haunting is toggled off Open the popup → confirm the toggle is ON. Settings → Timing → reduce "Minimum time on tab" to 5 seconds.
Ghosts appear on every tab instantly minDelay was set to 0 and maxPerHour is high Settings → Timing → set minDelay to at least 30 seconds for a natural feel.
Ghost appears on banking or medical sites The domain wasn't added to the whitelist Settings → Filters → add the domain to the Whitelist field (one domain per line, no www.).
Sound plays at 2 AM even with quiet hours set Quiet hours start/end times not saved after editing Always click Save Settings at the bottom of the Settings page after making any change.
Exorcised a tab by mistake and want it back Exorcism is permanent for that URL Open the Graveyard (🪦 from popup), search for the URL, and click Resurrect to reopen it. The exorcism block only prevents future haunting, not manual access.
Ghost appears on a PDF or Chrome Web Store page This should not happen — these pages are blocked by URL check If this occurs, report it via the Chrome Web Store support page. The extension skips any URL that doesn't begin with http:// or https://.
Ghost appears but no sound plays Browser blocked audio autoplay (common on first run) Click anywhere on the page once before the ghost is expected to appear. Chrome allows audio after a user gesture on the page.

Accuracy and Reliability Notes

🔬

Time on Tab accuracy: The extension records open time when the tab's status changes to "complete" (page fully loaded), not when the browser tab is first created. This means actual reading time is measured, not the loading time. If a page takes 8 seconds to load and you close it after 15 seconds of reading, timeOnTab will be approximately 15 seconds — accurate to within ±1 second due to Math.floor() rounding.

Schedule accuracy: Ghost delays use chrome.alarms, which guarantees a minimum firing granularity of 1 minute per Chrome's Manifest V3 specification. Ghosts scheduled for less than 60 seconds ahead will still fire, but Chrome may batch them to the next minute boundary. This is a Chrome platform constraint, not a bug.

All processing is local: Every formula runs inside your browser. No browsing data, tab URLs, or guilt scores are ever transmitted to any external server.

Real-World Usage Scenarios

Scenario 1: The Developer Who Closes Too Many Stack Overflow Tabs

A front-end developer opens 6 Stack Overflow tabs while debugging a React issue. After fixing it, they close all 6. The Nerd ghost fires 20 minutes later: "I was a Stack Overflow tab. Still couldn't fix it, could you?" They realise one of the closed tabs contained a different approach they hadn't tried. They click Resurrect in the Graveyard and save 45 minutes of re-searching.

Scenario 2: The Online Shopper Who Dismissed a Sale

A user opens a product page during a 24-hour sale event, spends 4 minutes on it, and closes it after deciding to "think about it." The Shopper ghost fires 2 hours later: "That sale ended at midnight. I hope it was worth it." The user checks the Graveyard, finds the URL, and reopens the product page with 3 hours of the sale remaining.

Scenario 3: The Researcher Who Closed Before Saving

A student closes a JSTOR article after reading the abstract but before bookmarking it. The Scholar ghost fires 45 minutes into their writing session: "The answer was in my third paragraph." They click Visit Again, reopen the article, and cite it in their essay.

Frequently Asked Questions

No. The extension uses a Manifest V3 service worker that only activates on tab events and alarm fires, then goes dormant again. It has no persistent background process. Storage is local to your browser. The ghost overlay is injected only when needed and removed immediately after dismissal, leaving no persistent DOM modification.
Tab Haunting reads only the tab's URL, page title, favicon URL, and the timestamp of when it was opened and closed. It does not read page body text, form inputs, cookies, passwords, or any other page content. No data leaves your browser — everything is stored in chrome.storage.local on your device only.
Clicking "Banish Forever" on a ghost permanently adds that URL to the Exorcism Log, which prevents any future ghost from appearing for that specific URL. The URL still appears in your Graveyard history — exorcism only blocks future hauntings, not past records. The tab is also still accessible via your regular browser history. You can still manually resurrect it from the Graveyard.
Ghosts stay in the queue for 7 days by default. A nightly purge removes entries older than this threshold. If you closed a tab 5 days ago and set maxDelay to several days, it's possible the ghost fires close to the 7-day limit. To prevent this, reduce maxDelay to 2 hours or less in Settings → Timing.
The ghost appears on the tab you have open at the time the alarm fires — not the tab that was closed. To prevent ghosts from appearing when you're on sensitive sites, add those domains to your Whitelist in Settings → Filters. Whitelisted tabs are also never haunted when closed, so this protects you on both sides.
Uninstalling the extension from chrome://extensions will remove all data stored by Tab Haunting, including the ghost queue, graveyard, exorcism log, and settings. Alternatively, to clear just the ghost queue without uninstalling, click "Exorcise All" from the popup — this clears all pending ghosts.
Incognito haunting is off by default to protect your privacy. To enable it, go to Settings → Filters → toggle "Allow haunting in incognito windows." You must also grant the extension access to incognito mode from chrome://extensions → Tab Haunting → "Allow in incognito."
🔍

The ExtensionHub.app Standard

VERIFIED BROWSER EXTENSION RESOURCE

🧪

Experience (Real-World Tested)

Curated by extension developers with 10+ years of hands-on browser extension experience across Chrome, Firefox, and Edge.

🎯

Expertise (Engineer-Vetted)

Every extension undergoes technical review for code quality, security, and performance by certified software engineers.

🏛️

Authority (Industry Trusted)

Listed in Chrome Web Store and Firefox Add-ons with high user ratings. Compliance with GDPR and CCPA.

🛡️

Trustworthy (Privacy First)

Zero data collection. No tracking, no logins, no cookies. Your privacy is our priority — always.

🔒 SSL Encrypted ⭐ 4.8/5 User Rating 📅 Updated Weekly 👨‍💻 50,000+ Downloads 🌍 Global User Base

📧 Never Miss a Great Extension

Get weekly picks, new releases, and updates straight to your inbox. No spam, ever.

☑️ I agree to the Privacy Policy

👋 About Me — Muhiuddin Alam

Hello, I'm Muhiuddin Alam — founder, curator, and your guide to the best browser extensions. I'm a browser extension expert, developer advocate, and the creator of ExtensionHub.app, a curated resource for discovering powerful, verified browser tools for productivity, AI, trading, shopping, privacy, and more.

With over 10+ years in web development and browser extension ecosystems, I've helped thousands of users enhance their browsing experience. I run ExtensionHub.app, where I share carefully vetted browser extensions and expert resources, all organized into 13 clear categories — from Accessibility to Shopping.

You'll also find my writing on:

Based in New York, I research, test, and review extensions daily. Every tool on ExtensionHub undergoes a rigorous review process aligned with The ExtensionHub Standard — ensuring it is 🧪 Experience (Real-World Tested), 🎯 Expertise (Engineer-Vetted), 🏛️ Authority (Industry Trusted), and 🛡️ Trustworthy (Privacy First).

🔍 Find the Perfect Browser Extension

Discover 176+ browser extensions across 13 curated categories for productivity, AI, trading, shopping, privacy, security, accessibility, and more. Every extension is tested for security, performance, and reliability before being recommended.

🌐 About ExtensionHub.app

Curated Browser Extensions • Productivity Tools • Privacy Solutions • Developer Resources

ExtensionHub.app helps you discover the best browser extensions for Chrome, Firefox, Edge, and more. 176+ extensions organized across 13 clear categories — from Accessibility to Shopping. Every extension is tested for security, performance, and reliability before being recommended. Clear reviews. Expert curation. Trusted resources.

I am Muhiuddin Alam, Founder and Chief Editor of ExtensionHub.app. My mission is to provide carefully vetted browser extensions and digital tools that enhance productivity, protect privacy, and improve your browsing experience.

I've built a comprehensive extension ecosystem — from productivity boosters and developer tools to accessibility aids, shopping assistants, and trading resources. Each extension is tested across multiple browsers to ensure compatibility and performance.

Every extension on ExtensionHub.app undergoes a rigorous review process aligned with The ExtensionHub Standard:

  • 🧪 Experience (Real-World Tested) — Curated by extension developers with 10+ years of hands-on browser extension experience across Chrome, Firefox, and Edge.
  • 🎯 Expertise (Engineer-Vetted) — Every extension undergoes technical review for code quality, security, and performance by certified software engineers.
  • 🏛️ Authority (Industry Trusted) — Listed in Chrome Web Store and Firefox Add-ons with high user ratings. Compliance with GDPR and CCPA.
  • 🛡️ Trustworthy (Privacy First) — Zero data collection. No tracking, no logins, no cookies. Your privacy is our priority — always.

From productivity boosters and developer tools to accessibility aids, shopping assistants, and trading resources — we cover what matters to modern web users. Save time, enhance privacy, and boost productivity with our expert-curated extension guides.

With ExtensionHub.app, you can discover trusted extensions, understand privacy implications, compare similar tools, and make confident decisions about the digital tools you use every day. 50,000+ downloads and a ⭐ 4.8/5 user rating speak to the trust our community places in our curation.