What Blast is — and what makes it different
Buffer, Hootsuite, and Sprout Social solve a real problem: posting to multiple social platforms without logging in and out of each one. But they share a fundamental limitation — they treat the web as the universe. Text your audience? Not a feature. WhatsApp broadcast? Find another tool. And all of them hold your API credentials on their servers.
Blast is my answer to both of those constraints. It's a self-hosted multi-platform broadcaster that sends a single composed post to all twelve of SMS, Email, WhatsApp, X, Instagram, Facebook, LinkedIn, TikTok, Threads, Telegram, Reddit, and Pinterest simultaneously. Your API credentials never touch a third-party server.
Architecture
The frontend is React 18, structured around a strict MVVM pattern with enforced layer boundaries. The model layer is eight pure JavaScript modules — none of which import React or touch the DOM. The viewmodel layer is six React hooks. The view layer is twenty components. The entire frontend bundles to a single self-contained HTML file using esbuild — no CDN calls at runtime, works offline.
The backend proxy is a Node.js HTTP server written with a deliberate constraint: zero npm dependencies. Every module uses only Node 22 built-ins — node:http, node:https, node:crypto, node:fs, node:sqlite. The practical effect is a proxy you can deploy to Render, Railway, or Fly.io in about five minutes with no install surprises and no supply-chain exposure.
Features, as they fit together
The core workflow is composing a post and blasting it everywhere. But the feature set earns its keep in the surrounding workflows. The built-in Claude AI writing assistant generates four platform-aware variants in parallel — punchy, formal, casual, question — or accepts a free-form prompt. Drafts persist in history with a DRAFT badge and load back into the composer with one click. Scheduling saves a job to the proxy's SQLite queue; the scheduler fires jobs at their target time and posts a Slack Block Kit notification on completion.
The calendar view renders a full month grid showing text previews and platform icons per post. When a proxy is configured, it syncs server-side scheduled jobs with local history — multiple users pointing at the same proxy see each other's scheduled posts. After posts go out, a Stats button fetches live engagement numbers from each platform. An Inbox button fetches replies and renders them as a read-only thread.
Testing
260 unit tests cover all eight model modules using node --test — no install whatsoever. 29 proxy tests cover every route, auth, CORS, upload, and Slack notifications. 51 Playwright E2E tests run against the pre-compiled HTML bundle across desktop, iPhone, and Android configurations. Total: ~460 tests across the pyramid.
What wasn't built, and why
OAuth redirect flows require a hosted callback URL — pasting tokens is more honest about the trade-off. Token auto-refresh was scoped out because only a subset of platforms support it; the expiry warning system handles this transparently. Client-side scheduling only works if the browser tab stays open, so the proxy scheduler is the correct architecture. An Electron wrapper adds 200+ MB of binary dependency for an app that already distributes as a single HTML file.
Building with an AI collaborator
Blast was built entirely within a single extended Claude conversation — architecture, implementation, debugging, refactoring, testing, and documentation, all iteratively through dialogue. The discipline that mattered most was reading before writing: before touching any file, the relevant existing code was read in full. Feature prioritisation happened through multiple SWOT analyses. The constraint of working within a single conversation turned out to be a feature — it kept the context coherent across weeks of work in a way that scattered prompts wouldn't have.