{"slug": "i-shipped-an-ai-side-panel-in-2-weekends", "title": "I shipped an AI side panel in 2 weekends", "summary": "A developer built a Chrome extension that lets users highlight text and send it to multiple AI models via a side panel in two weekends. The extension supports OpenAI, Claude, Gemini, and DeepSeek, but only gained 15 users in five weeks, highlighting the challenge of distribution over building.", "body_md": "I am going to talk about shipping speed, because that is what the last two months have been about for me.\n\nI had an idea for a Chrome extension: highlight text, send it to ChatGPT, see the reply in a side panel. I had used three different tools that did parts of this and none of them worked the way I wanted.\n\nI gave myself two weekends. Saturday and Sunday, week one, build the MVP. Saturday and Sunday, week two, polish. Monday, submit to the Chrome Web Store. That was the plan.\n\nI started Saturday morning at 9. By lunch I had a popup window that opened ChatGPT with the selected text pre-filled. That was the wrong UX. It broke the workflow because now I had two things on screen and the original page was pushed aside.\n\nI ate lunch, came back, and decided to do a side panel instead. The Chrome side panel API exists. It is documented in like 4 paragraphs and most of the documentation is about coloring and sizing. I had to read the source of one example extension to figure out how to make the panel persist across page navigations.\n\nBy Sunday evening I had: select text, click a button, see a ChatGPT-style reply in a side panel. The reply was hardcoded to a single fake response. The selected text was passed via `chrome.storage.session`\n\n. Nothing was wired to a real model yet.\n\nTotal weekend 1 time: about 14 hours. That included a 2-hour detour into the popup-window approach that I threw away.\n\nSaturday was wiring it to the OpenAI API directly. No backend. The user's API key goes into Chrome local storage. The selected text gets sent to OpenAI with a system prompt I wrote. The reply streams into the side panel.\n\nThat was the day I learned that Chrome extensions cannot use `fetch`\n\nfrom a side panel because of a CSP issue I did not know about. I burned 3 hours on it. The fix was to put the `fetch`\n\ncall in the background service worker and stream the response back to the side panel via `chrome.runtime.sendMessage`\n\n.\n\nBy Saturday night it worked end to end with OpenAI.\n\nSunday was multi-model. Add Claude, add Gemini, add DeepSeek. Each one needed a different base URL, a different request shape, a different way to parse the streaming response. The OpenAI-compatible APIs (Claude via OpenRouter, Gemini via OpenRouter, DeepSeek direct) made this easier than it would have been, but it still took 6 hours of testing each one.\n\nBy Sunday night I had 4 models working. I packaged it and uploaded it to the Chrome Web Store.\n\nTotal weekend 2 time: about 16 hours. The CSP debugging ate a real chunk of Saturday.\n\nChrome Web Store review took 3 days. It was approved on Wednesday. I posted about it on Reddit, X, and Indie Hackers.\n\nThe first 48 hours I got about 9 users. That is much fewer than I hoped. The next 5 weeks I got 6 more. So 15 users after about 5 weeks total.\n\n**1. Shipping is faster than I thought.** Two weekends was realistic because the side panel API is small and most of the work was plumbing I had done before.\n\n**2. CSP is going to waste your time.** If you build a Chrome extension with a side panel that talks to external APIs, budget 4 hours for the service worker + sendMessage dance. There is no good documentation for it.\n\n**3. The OpenAI-compatible API ecosystem is the real win.** Three of the four models I support are reachable through the OpenAI request shape. That cut my integration work in half.\n\n**4. 15 users in 5 weeks is not enough.** I knew this intellectually. Now I know it from sitting at my dashboard at 11pm refreshing the count. Distribution is the whole game. Building is the easy part.\n\n**5. The thing that slowed me down the most was not building. It was convincing myself the side panel UX was the right one.** I should have started there instead of the popup window.\n\nI would spend more time on the listing page before submission. The first 48 hours of traffic came mostly from people who clicked my Reddit post, landed on the Chrome Web Store page, and bounced. The description was not clear enough about what the extension does in the first sentence.\n\nThat is a fixable problem. The hard part is done.\n\nIf you are building a Chrome extension and want to see how the side panel is wired, the source is on GitHub. The relevant file is `sidepanel.js`\n\nand the service worker is `background.js`\n\n. There are comments.\n\nWhat did your last two-weekend project look like?", "url": "https://wpnews.pro/news/i-shipped-an-ai-side-panel-in-2-weekends", "canonical_source": "https://dev.to/cwsaibuddy/i-shipped-an-ai-side-panel-in-2-weekends-5e5h", "published_at": "2026-06-28 04:06:28+00:00", "updated_at": "2026-06-28 04:33:26.214187+00:00", "lang": "en", "topics": ["developer-tools", "large-language-models", "ai-tools", "generative-ai"], "entities": ["Chrome", "OpenAI", "Claude", "Gemini", "DeepSeek", "OpenRouter", "Chrome Web Store", "Reddit"], "alternates": {"html": "https://wpnews.pro/news/i-shipped-an-ai-side-panel-in-2-weekends", "markdown": "https://wpnews.pro/news/i-shipped-an-ai-side-panel-in-2-weekends.md", "text": "https://wpnews.pro/news/i-shipped-an-ai-side-panel-in-2-weekends.txt", "jsonld": "https://wpnews.pro/news/i-shipped-an-ai-side-panel-in-2-weekends.jsonld"}}