Skip to content

owklama/extudio

Extudio

YOUR BRAND. YOUR VOICE. YOUR STUDIO.

Alpha status MIT License React 19 TypeScript PRs Welcome

Extudio is a local-first content studio for X/Twitter that you configure for your brand. Define your voice, terminology, and strategy in a single brand.json file — every AI prompt, content suggestion, and tone check reflects your brand. No accounts. No SaaS. No vendor lock-in.

If you want a personal, brand-aware content studio that feels fast, local, and completely yours, this is it.

Getting Started · Features · Brand Config · Project Docs

Product Preview

Extudio — Product Preview

Quick Start

Runtime: Bun (package manager + runtime). Node: 20+ (.nvmrc included).

git clone https://github.com/owklama/extudio.git
cd extudio
bun install
bun run dev

Open localhost:5173. The onboarding wizard walks you through brand setup on first run.

Prerequisites

  • Bun — package manager
  • AI text provider — one of:
    • Local CLI (no keys, nothing leaves your machine): Claude CLI, codex, opencode, or gemini CLI
    • API key (configured in Settings): Anthropic, OpenAI, OpenRouter, DeepSeek, xAI, or Perplexity
  • Optional: OpenAI API key — for image generation via GPT Image 1
  • Optional: Gemini API key — for image generation via Nano Banana (Gemini)
  • Optional: fal.ai API key — for image generation via FLUX Pro 1.1 / FLUX Schnell
  • Optional: X Developer App — for posting directly to X

Environment Setup

cp .env.example .env
# Fill in your keys

.env holds the X OAuth app and optional image-provider keys. Text-generation providers (CLI or API) are picked in Settings at runtime.

Highlights

  • Overview Dashboard — welcome screen with content status and quick-action cards to jump into any workflow.
  • Compose Wizard — step-by-step AI tweet/thread editor with full brand context injection.
  • Kanban Queue — 4-column drag-and-drop pipeline (Draft → Ready → Scheduled → Posted) via @dnd-kit.
  • Calendar Grid — weekly schedule view with configurable posting slots.
  • X-Faithful Preview — pixel-accurate tweet rendering at desktop, tablet, and mobile sizes.
  • Article Wizard — long-form X article generation with audience, angle, and depth controls.
  • Brand Dashboard — live overview of your glossary, tone guide, pillars, SEO keywords, and messaging — all editable in-app.
  • Tweet Bank — pre-written tweet library with search, filtering, batch operations, and AI variations.
  • AI Chat — multi-turn brand-aware chat with structured outputs (tables, suggestions, actionable insights).
  • Reply Generator — paste a tweet URL, fetch the original, and generate brand-tone replies in CEO, Brand, or Casual voice.
  • Image Studio — AI-generated visuals with 8 art styles, 5 aspect ratios, and multiple formats via OpenAI, Gemini, or fal (FLUX).
  • Profile & Stats — content analytics dashboard with category distribution, pillar coverage, and schedule overview.
  • X Integration — connect your X account via OAuth 2.0 and post directly from the app.
  • Bring your own AI — swap between local CLIs (Claude, Codex, OpenCode, Gemini) and direct APIs (Anthropic, OpenAI, OpenRouter, DeepSeek, xAI, Perplexity). CLI mode keeps everything on your machine.

How It Works

flowchart TB
  brand["brand.json<br/>brand config + tweet bank"]
  statefile["data/studio-data.json<br/>persisted studio state"]
  chats["data/chat-sessions/*.json<br/>saved chat history"]
  tokens[".x-tokens.json<br/>X OAuth tokens"]
  local["localStorage<br/>fast boot cache"]

  subgraph Browser["Browser — React SPA"]
    views["13 views + app shell<br/>Compose, Queue, Calendar, Article, Brand, Preview, Overview, Settings, Reply, Bank, Profile, Imagine, Chat"]
    store["StudioProvider<br/>global state + hydration"]
    engine["Content engine + prompt builders<br/>brand-aware text generation"]
  end

  subgraph Server["Vite dev-server middleware"]
    brandapi["/api/brand<br/>/api/brand-tweets"]
    stateapi["/api/state"]
    gen["/api/generate<br/>SSE streaming"]
    chatapi["/api/chat-sessions"]
    img["/api/generate-image<br/>/api/generate-cover"]
    xapi["/api/x/*"]
  end

  subgraph Providers["Execution targets"]
    cli["Local AI CLIs<br/>Claude Code · Codex · OpenCode · Gemini"]
    textapi["Text APIs<br/>Anthropic · OpenAI · OpenRouter · DeepSeek · xAI · Perplexity"]
    imgapi["Image APIs<br/>OpenAI · Gemini"]
    xext["X API<br/>OAuth 2.0 + posting"]
  end

  brand -->|"imported via src/config/brand.ts"| views
  views --> brandapi
  brandapi <--> brand

  views --> store
  store <--> local
  store <--> stateapi
  stateapi <--> statefile

  views --> engine
  engine --> gen
  gen -. "SSE stream" .-> views
  gen --> cli
  gen --> textapi

  views --> chatapi
  chatapi <--> chats

  views --> img
  img --> imgapi

  views --> xapi
  xapi <--> tokens
  xapi <--> xext
Loading

brand.json is imported directly into the app via src/config/brand.ts, while runtime brand edits go through the Vite middleware at src/server/brand.ts. Studio state hydrates from data/studio-data.json through /api/state and is mirrored to localStorage for fast boot. Text generation runs through src/server/claude.ts: CLI mode stays local, API mode streams from the configured provider, and responses come back over Server-Sent Events.

Brand Configuration

Everything brand-specific lives in one file: brand.json at the project root.

Edit it and the entire app adapts — AI prompts, tone, content categories, glossary, tweet bank, and UI labels. The more context you provide, the better the AI matches your brand.

Full brand.json reference
Section What it controls
app App name, localStorage keys, default X handle and display name
brand Name, URL, tagline, positioning, audience, features, trust signals
glossary Terms and plain-language definitions — AI uses these to simplify jargon
contentPillars Your content strategy themes that guide AI generation
tweetCategories Categories with accent colors for organizing tweet cards
toneGuide Brand voice description + do/don't rules for AI tone
contentPatterns Templates for social hooks, CTAs, hero copy, feature copy
seoKeywords Keywords the AI weaves into generated content
audienceSegments Target personas with motivations and blockers
brandDifferentiators What makes you different — injected into AI prompts
brandMessages Core messaging lanes with bullet points
categoryPlaybooks Per-category mission, themes, proof points, and CTAs
brandKit Personality traits, word lists, trust lines, social bios, headlines
topicAngles Content angles: myth-busting, how-to, comparison, deep-dive, etc.
tweets Pre-written tweet bank for reference and reuse
Minimal brand.json to get started
{
  "app": {
    "name": "My Studio",
    "storageKey": "my-studio",
    "themeStorageKey": "my-studio-theme",
    "exportFilename": "my-studio-backup.json",
    "defaultHandle": "my_handle",
    "defaultDisplayName": "My Brand",
    "defaultAvatarUrl": "/favicon.ico"
  },
  "brand": {
    "name": "My Brand",
    "tagline": "Your tagline here",
    "oneLiner": "What you do in one sentence",
    "positioning": "How you're positioned in the market",
    "problem": "The problem you solve",
    "solution": "How you solve it",
    "url": "https://yourbrand.com",
    "platforms": [],
    "features": [],
    "trustSignals": [],
    "audience": "Your target audience"
  },
  "glossary": [],
  "contentPillars": [],
  "tweetCategories": [
    { "id": "education", "label": "Education", "color": "#6ee7b7" },
    { "id": "discovery", "label": "Discovery", "color": "#67e8f9" },
    { "id": "data", "label": "Data / Tips", "color": "#fbbf24" },
    { "id": "engagement", "label": "Engagement", "color": "#c084fc" }
  ],
  "toneGuide": { "voice": "Your brand voice", "do": [], "dont": [] }
}

Scripts

Command Description
bun run dev Start dev server with HMR
bun run build Production build
bun run preview Preview production build
bun run lint Run ESLint
bun run test Run tests (Vitest)
bun run format Format with Prettier
bun run format:check Check formatting
bun run storybook Start Storybook on localhost:6006
bun run build-storybook Build static Storybook to storybook-static/

Storybook

The full UI stack is documented in Storybook — primitives in components/ui, tweet rendering, foundations (colors, typography), and shared utilities. Stories live in src/stories/ and the config is in .storybook/.

bun run storybook

Components that depend on the global studio store (sidebar, app-background, modals, view shells) are intentionally not storied — they only make sense inside the running app.

Project Docs

Contributing Security Code of Conduct License

Contributing

Contributions are welcome.

Security
  • Report vulnerabilities privately via SECURITY.md.
  • Do not open public GitHub issues for exploitable security problems.
  • Security contact: security@extudio.dev

Code of Conduct
  • Community expectations live in CODE_OF_CONDUCT.md.
  • The project uses the Contributor Covenant.
  • Report conduct issues privately to security@extudio.dev.

License
  • Extudio is released under the MIT License.
  • Free to use, modify, and distribute — including for commercial purposes.

About

Open-source content studio for X/Twitter with AI writing, scheduling, Kanban, replies, and brand.json context.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages