Chrome Extensions synchronous calls - create window only after window
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Chrome extensions do not provide true synchronous window management. If you want to create a new window only after an existing one closes, the correct model is event-driven: open the first window, listen for its removal, and then trigger the next action when the windows.onRemoved event fires.
Core Sections
Why synchronous thinking does not fit
The Chrome extension APIs are asynchronous because the browser cannot block the whole extension while a window stays open. That means code like "create window A, wait synchronously, then create window B" is not how the API works.
Instead, you structure the logic around callbacks, promises, or listeners.
Basic event-listener approach
A simple pattern is:
- create the first window
- remember its window ID
- listen for
chrome.windows.onRemoved - when that same ID is removed, create the next window
This is the core idea. You are not making the API synchronous. You are expressing the dependency between two asynchronous events.
Promise-style wrapper for cleaner flow
If you prefer more structured code, wrap the open-and-wait logic in a promise.
This reads more like sequential logic, but it is still implemented with asynchronous events underneath.
Avoid global listeners that never detach
The biggest implementation detail is cleanup. If you attach windows.onRemoved listeners repeatedly and never remove them, you will create subtle bugs and duplicate actions later.
That is why both examples explicitly call removeListener once the relevant window closes.
Think about user cancellation and unrelated windows
The event fires for every window close, not just the popup you care about. Your handler must compare IDs and ignore unrelated removals. In larger extensions, that detail matters because users can open and close many browser windows while your flow is active.
If the first window may be closed indirectly or fail to open, you may also want timeout or error-handling logic instead of assuming a perfect sequence.
In Manifest V3 extensions, keep in mind that background logic may live in a service worker. If later steps depend on remembering a window ID across events, storing that ID in extension state rather than in transient UI code makes the sequence much more reliable.
Common Pitfalls
- Trying to write Chrome extension window code as if the API were synchronously blocking.
- Listening for
windows.onRemovedwithout checking the specific window ID you care about. - Forgetting to remove the event listener after it has served its purpose.
- Assuming no other browser windows will close while your extension flow is running.
- Building the sequence around sleeps or polling instead of reacting to the actual close event.
Summary
- Chrome extensions do not offer true synchronous calls for window lifecycle control.
- The correct pattern is event-driven: create a window, then react when
windows.onRemovedreports that it closed. - Matching the removed window ID is essential because the event fires for every window.
- Promise wrappers can make the code read sequentially while still staying asynchronous.
- Always remove listeners after use to avoid duplicate actions and hard-to-debug state leaks.

