Skip to main content
Product Design, Development
Live

Meridian Social

Schedule everywhere. Own your voice across every platform.

meridiansocial.app ↗
// At a glance

Multi-platform publishing for creators and small teams running more than one voice. Eleven platforms, each on its own terms.

Role
Product Design · Engineering · Brand
Stack
Node · PostgreSQL · React · BullMQ
// The problem

Social media management tools are either bloated enterprise dashboards or stripped-down schedulers that break on their third platform. Creators and small teams don't need analytics suites or team approval chains. They need to write a post, choose where it goes, and trust that it gets there.

Most tools treat platforms as interchangeable. They're not. Twitter has a 280-character ceiling. Instagram favors visuals. LinkedIn rewards longer thought. Discord is a webhook. Bluesky uses app passwords. Each one has its own OAuth flow, its own API quirks, its own failure modes. A scheduling tool that doesn't account for these differences isn't a tool — it's a liability.

// The approach

One composer. Eleven platforms.

Each integration is purpose-built. OAuth where the platform requires it. PKCE for Twitter. Credential-based auth for Bluesky and Discord. Token refresh handling for platforms that expire access. No shortcuts. No abstractions that paper over differences.

Twitter
OAuth PKCE
LinkedIn
OAuth 2.0
Facebook
OAuth 2.0
Instagram
OAuth 2.0
TikTok
OAuth 2.0
YouTube
OAuth 2.0
Threads
OAuth 2.0
Pinterest
OAuth 2.0
Bluesky
App password
Discord
Webhook
Google Business
OAuth 2.0
// Design decisions
01
Multi-brand from day one

Agencies manage multiple clients. Creators run multiple identities. Meridian scopes everything — posts, connections, limits — per brand. Switch context without switching accounts.

02
Character limits are real constraints, not warnings

The composer shows per-platform character counts in real time. Twitter's 280 and LinkedIn's 2,200 aren't treated the same. The interface reflects the platform, not our preferences.

03
AI media generation built in

Text-to-image and image-to-video via Higgsfield. Not as a bolt-on feature with its own page — integrated directly into the compose flow. Write a prompt, generate media, attach it, schedule. One flow.

04
MCP server for autonomous operation

Sixteen tools exposed via the Model Context Protocol. Claude Code can create posts, schedule content, manage brands, generate media, and check queue status — all without the browser. For users who think in terminals, not dashboards.

05
Calendar as a first-class view

Not a roadmap feature. The calendar ships with drag-and-drop, week and month views, and click-to-edit. Scheduling is spatial, not just temporal.

06
Queue with live refresh

Scheduled posts update every 30 seconds. Time remaining is always accurate. Edit, delete, or publish immediately — without navigating away.

// Technical architecture
Runtime
Node.js (ESM)
Framework
Express.js
Database
PostgreSQL 15 via Prisma ORM
Job Queue
BullMQ + Redis 7
Auth
JWT + bcryptjs (14-day free trial)
Payments
Stripe (recurring subscriptions)
Storage
DigitalOcean Spaces (S3-compatible CDN)
AI Media
Higgsfield API (text-to-image, image-to-video)
MCP
@modelcontextprotocol/sdk (stdio transport)
Frontend
React 18, Vite, Tailwind CSS, Zustand
UI
Custom component library (shadcn-style)
Calendar
react-big-calendar
Deployment
Docker Compose, Dokploy
Why BullMQ over cron

Scheduled posts need retry logic, failure tracking, and cancellation. BullMQ gives us all three. Three retry attempts with exponential backoff. If Twitter's API throws a 429 at 3 AM, the post retries — then marks as failed with a reason the user can read.

Why Prisma

Typed schema. Auto-generated migrations. Platform connections scoped to brands with a unique constraint on platform + brand. The schema enforces relationships the application layer doesn't have to worry about.

Why a custom component library

We needed dark mode, glass morphism, and consistent spacing without importing a full design system. Ten components — all built to the same spec. Tailwind utilities underneath. No runtime CSS-in-JS overhead.

Why Zustand over Redux

Three slices of state: auth, theme, brands. Redux is infrastructure for a problem this size. Zustand is a function call.

// The model

Three tiers. Enforcement at every boundary.

Free
$0/mo

30 posts/month, 3 platforms per post, 1 brand. Watermark on published posts.

Pro
Paid/mo

Unlimited posts, all platforms, 1 brand. No watermark.

Agency
Paid/mo

Everything in Pro, plus 5 brands. Multi-client management.

Plan limits are checked at post creation, not at publish time. No one schedules 50 posts only to find out at midnight that they hit a wall.

// What we learned

Platform integrations are where ambition meets bureaucracy. Every OAuth flow has its own interpretation of the spec. Twitter's PKCE implementation requires a code verifier stored with a 10-minute TTL. Instagram demands a connected Facebook business account. Pinterest needs a separate landing page for app review. Each one is a week of work disguised as an afternoon.

The MCP server changed how we use our own product. Scheduling a week of content from a terminal — no browser, no clicking — turned a 30-minute task into a 3-minute conversation. We built it for users. We kept it because we couldn't go back.

The endorsement watermark for free users was a deliberate trade. "Posted with meridiansocial.app" at the bottom of every post. Not hidden. Not aggressive. Just present. The users who convert to Pro do it to remove five words. That's the kind of pricing signal that works.

← PreviousScoutMapNext →All work
// Work with us

Have something worth building?

We take on a small number of client projects alongside our own products. If it's ambitious and the problem is real, we're interested.

Start a conversation