Chrome Extension Extension Uninstall — Best Practices

6 min read

Extension Uninstall Patterns

Overview

When users uninstall your Chrome extension, you have an opportunity to collect valuable feedback and clean up resources. This guide covers patterns for handling extension uninstallation gracefully.

Uninstall URL

Set an uninstall URL that opens automatically when users uninstall your extension:

chrome.runtime.setUninstallURL('https://example.com/uninstall-survey');
chrome.runtime.onInstalled.addListener((details) => {
  if (details.reason === 'install') {
    // Generate anonymous ID for tracking
    const anonymousId = crypto.randomUUID();
    chrome.storage.local.set({ anonymousId });
    
    // Set uninstall URL with tracking
    chrome.runtime.setUninstallURL(
      `https://example.com/uninstall-survey?uid=${anonymousId}`
    );
  }
});

Uninstall Survey Best Practices

Example questions:

Cleanup on Uninstall

Chrome automatically clears the following on uninstall:

Manual cleanup required for:

// Server-side cleanup example (triggered via uninstall URL)
app.get('/uninstall-survey', (req, res) => {
  const anonymousId = req.query.uid;
  // Call your API to delete user data
  await userService.deleteUserData(anonymousId);
  res.send('Thank you for your feedback!');
});

Detecting Uninstall (Self)

Extensions cannot directly detect their own uninstall from within the extension code. However:

chrome.runtime.onSuspend.addListener(() => {
  console.log('Extension is being unloaded');
  // Perform final cleanup tasks
  // Note: This runs on disable AND uninstall
});

Detecting Other Extension Uninstall

Use the chrome.management.onUninstalled listener to detect when other extensions are uninstalled:

// Requires "management" permission in manifest

chrome.management.onUninstalled.addListener((id) => {
  if (id === 'companion-extension-id') {
    console.log('Companion extension was uninstalled');
    // Notify user or disable related features
  }
});

Common use cases:

Self-Uninstall

Extensions can uninstall themselves programmatically:

chrome.management.uninstallSelf({ showConfirmDialog: true });
// Self-uninstall after license expiration
function handleLicenseExpired() {
  alert('Your license has expired. The extension will now uninstall.');
  chrome.management.uninstallSelf({ showConfirmDialog: false });
}

Code Examples

Complete Uninstall URL with Tracking

// In background script
chrome.runtime.onInstalled.addListener(async (details) => {
  if (details.reason === 'install') {
    const anonymousId = generateAnonymousId();
    await chrome.storage.local.set({ anonymousId });
    
    chrome.runtime.setUninstallURL(
      `https://yoursite.com/uninstall?ref=chrome&id=${anonymousId}`
    );
  }
});

function generateAnonymousId() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
    const r = Math.random() * 16 | 0;
    return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
  });
}

Server-Side Cleanup

// Express.js example
app.get('/uninstall', async (req, res) => {
  const { id } = req.query;
  
  try {
    // Clean up user data
    await db.users.delete({ anonymousId: id });
    await analytics.trackEvent('extension_uninstall', { id });
    
    res.status(200).send('Cleanup complete');
  } catch (error) {
    res.status(500).send('Error processing uninstall');
  }
});

Self-Uninstall with Confirmation

document.getElementById('uninstall-btn').addEventListener('click', () => {
  if (confirm('Are you sure you want to uninstall this extension?')) {
    chrome.management.uninstallSelf({ showConfirmDialog: true });
  }
});

Companion Extension Detection

// Check if companion extension exists on startup
async function checkCompanionExtension() {
  try {
    const ext = await chrome.management.get('companion-extension-id');
    if (!ext.enabled) {
      showCompanionWarning();
    }
  } catch (e) {
    showCompanionWarning();
  }
}

// Listen for companion uninstall
chrome.management.onUninstalled.addListener((id) => {
  if (id === 'companion-extension-id') {
    showCompanionWarning();
  }
});

Cross-References

Part of the Chrome Extension Guide by theluckystrike. Built at zovo.one.