Skip to content

kevinreber/pixel-studio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

775 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🎨 Pixel Studio

AI-powered image and video generation platform with real-time progress, social features, and a built-in creator economy.

Pixel Studio is a full-stack web app where users generate images across many state-of-the-art models (OpenAI gpt-image-1, Stable Diffusion 3.5, Flux Pro / Dev / Schnell, Ideogram, FAL, Black Forest, Together, Replicate) and produce short videos via Runway, Luma, and Stability. It ships with collections, a following feed, comments and likes, achievements, a prompt marketplace, creator tipping, print-on-demand, an admin console, and a Tailwind-based design system with a persisted light/dark theme.

Built on Remix + Vite + React 18 + TypeScript, backed by PostgreSQL + Prisma, with Upstash QStash powering the async generation queue and WebSockets streaming live progress to the client.

πŸ“Έ Screenshots

A tour of the redesigned UI (PR #150, June 2026). All captures come from the live app β€” see pr-screenshots/ for the full historical set.

Desktop

Landing Explore
Landing page Explore page
Create β€” Image Create β€” Video
Create image Create video
Following Feed Profile
Feed Profile
What's New Admin Overview
What's new Admin overview

Mobile

Mobile landing Mobile feed Mobile create Mobile profile

✨ Features

Generation

  • πŸ–ΌοΈ Images across 8 providers β€” OpenAI (gpt-image-1 with dall-e-3 fallback), Stable Diffusion 3.5 (Large / Turbo / Medium), Stable Image Core & Ultra, Flux Pro 1.1 / Dev / Schnell, Ideogram, FAL, Black Forest, Replicate, Together
  • 🎬 Video generation β€” Runway ML, Luma AI, Stability AI, with automatic thumbnail extraction
  • πŸ”€ Multi-model comparison β€” run one prompt across multiple models and compare the results side-by-side
  • 🌱 Image remixing β€” fork any image, track lineage through Image.parentId
  • ⚑ Async pipeline β€” Upstash QStash queues jobs, workers process them, WebSockets stream live progress to the UI

Social & community

  • πŸ—‚οΈ Collections β€” public, private, and premium (paid) collections of images
  • πŸ‘₯ Following feed β€” see new work from creators you follow
  • πŸ’¬ Comments, likes, replies β€” full nested-comment system on images and videos
  • πŸ† Achievements & login streaks β€” gamified engagement
  • πŸ›’ Prompt marketplace β€” sell and review high-quality prompts with built-in payouts
  • πŸ’° Tipping β€” send credits directly to other creators
  • πŸ–¨οΈ Print on demand β€” order physical prints of generated images

Monetization & ops

  • πŸ’³ Stripe-powered credits with full ledger (CreditTransaction)
  • πŸ“ˆ Analytics dashboards for users and admins, plus per-prompt performance and "style fingerprint" analysis
  • πŸ›‘οΈ Admin console β€” users, credits, models, external services, tokens, deletion audit logs, engagement, blog management
  • πŸ“ Blog / tutorials with SEO metadata
  • πŸŒ— Light & dark themes persisted on the User record
  • πŸ“± Mobile-first redesign β€” sidebar collapses into a bottom nav + slide-up sheet on small screens

πŸ› οΈ Tech Stack

Layer Technology
Framework Remix 2.16 + React 18 + TypeScript 5 + Vite 5
Styling TailwindCSS 3, custom design tokens (app/globals.css), Radix UI primitives, shadcn/ui, Lucide icons
Database PostgreSQL + Prisma ORM 5 (43 models)
Auth Remix Auth + Google OAuth; Supabase v2 auth migration in progress
State Zustand (client) + React Context (generation progress)
Queue Upstash QStash (default) β€” Apache Kafka pipeline available but on hold
Cache Upstash Redis
Storage AWS S3
Real-time Native WebSocket server
AI (Images) OpenAI, Hugging Face, FAL, Ideogram, Replicate, Together, Black Forest Labs, Stability
AI (Video) Runway ML, Luma AI, Stability AI
Payments Stripe
Logging Winston + OpenTelemetry (OTLP HTTP)
Monitoring Sentry, Vercel Analytics, PostHog
Testing Vitest 4, Playwright
Tooling Husky + lint-staged, ESLint (Airbnb-ish), Prettier
Deploy Vercel (primary), Express production server (server.js)

πŸš€ Quick Start

Prerequisites

  • Node.js β‰₯ 20
  • PostgreSQL (local or hosted β€” Supabase, Neon, RDS, etc.)
  • Upstash account for Redis + QStash
  • API keys for at least one image provider (OpenAI is enough to get started)

Kafka and Docker are not required in the default configuration. QStash handles async generation out of the box.

1. Clone & install

git clone https://github.com/kevinreber/pixel-studio.git
cd pixel-studio
npm install

2. Configure environment

cp env.example .env
# Edit .env β€” see "Environment Variables" below

At minimum, fill in DATABASE_URL, SESSION_SECRET, GOOGLE_CLIENT_ID/SECRET, OPENAI_API_KEY, UPSTASH_REDIS_REST_*, QSTASH_*, and the AWS S3 keys.

3. Set up the database

npx prisma generate
npx prisma db push

4. Run the dev server

npm run dev

The app boots at http://localhost:5173. Image jobs flow through QStash and progress updates stream via WebSocket β€” no extra processes needed.

(Optional) Stripe webhooks

npm run stripe:listen

(Optional) Activate the Kafka pipeline

Kafka is fully wired up but parked to save infrastructure cost. To turn it on, set QUEUE_BACKEND=kafka and the KAFKA_* vars in .env, then run:

docker-compose -f infrastructure/kafka/docker-compose.kafka.yml up -d
npm run kafka:create-topics
npm run kafka:consumer       # workers
npm run kafka:websocket      # progress stream

πŸ“‹ Environment Variables

See env.example for the full annotated template. The required groups are:

# Database
DATABASE_URL=
DIRECT_URL=

# Auth
SESSION_SECRET=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
SUPABASE_URL=
SUPABASE_ANON_KEY=

# Image providers (at least one)
OPENAI_API_KEY=
HUGGINGFACE_API_KEY=
FAL_KEY=
REPLICATE_API_TOKEN=
IDEOGRAM_API_KEY=
TOGETHER_API_KEY=
BFL_API_KEY=

# Video providers
RUNWAY_API_KEY=
LUMAAI_API_KEY=
STABILITY_API_KEY=

# Cache & queue
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
QSTASH_TOKEN=
QSTASH_CURRENT_SIGNING_KEY=
QSTASH_NEXT_SIGNING_KEY=
QUEUE_BACKEND=qstash         # "qstash" (default) or "kafka"

# Storage
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_REGION=us-east-1
S3_BUCKET_NAME=

# Payments
STRIPE_PUBLIC_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=

# Monitoring (optional but recommended)
SENTRY_ORG=
SENTRY_PROJECT=
SENTRY_AUTH_TOKEN=

πŸ“– Available Scripts

Development

npm run dev              # Vite dev server (http://localhost:5173)
npm run build            # Production build (remix vite:build)
npm run start            # Start production server (remix-serve)
npm run typecheck        # TypeScript checks
npm run lint             # ESLint

Testing

npm run test             # Vitest watch mode
npm run test:run         # Vitest single run
npm run test:coverage    # Vitest with v8 coverage
npm run test:e2e         # Playwright E2E suite
npm run test:e2e:ui      # Playwright UI mode

Database

npx prisma studio        # Visual DB browser
npx prisma db push       # Push schema
npx prisma generate      # Generate client
npx prisma migrate dev   # Create migration

Kafka (only if QUEUE_BACKEND=kafka)

npm run kafka:create-topics
npm run kafka:consumer
npm run kafka:websocket
npm run kafka:health
npm run kafka:monitor

Utilities

npm run stripe:listen              # Stripe webhook forwarding β†’ localhost:5173/webhook
npm run video:backfill-thumbnails  # Backfill thumbnails for existing videos

πŸ—οΈ Architecture

Async generation flow (QStash, default)

graph TD
    A["Create form"] --> B["Remix action"]
    B --> C["QStash publish"]
    C --> D["/api/queue/process-image"]
    D --> E["Provider SDK call"]
    E --> F["S3 upload"]
    F --> G["Postgres update"]
    G --> H["WebSocket broadcast"]
    H --> I["Live UI progress"]
    I --> J["Redirect to results"]
Loading

Project structure

pixel-studio/
β”œβ”€β”€ app/
β”‚   β”œβ”€β”€ components/              # 55 UI components (incl. shadcn primitives + ps/* design system)
β”‚   β”œβ”€β”€ config/                  # Models, pricing, breakpoints, build logs
β”‚   β”œβ”€β”€ contexts/                # Generation progress context
β”‚   β”œβ”€β”€ hooks/                   # Custom React hooks
β”‚   β”œβ”€β”€ pages/                   # Page-level components
β”‚   β”œβ”€β”€ routes/                  # 96 Remix routes (pages + 47 API endpoints)
β”‚   β”œβ”€β”€ schemas/                 # Zod validation
β”‚   β”œβ”€β”€ server/                  # Server-only utilities (74 files)
β”‚   β”œβ”€β”€ services/                # Business logic (35 files)
β”‚   β”œβ”€β”€ utils/                   # Shared utilities
β”‚   └── client/                  # Client-only utilities
β”œβ”€β”€ infrastructure/kafka/        # Optional Kafka deployment (Docker, AWS MSK)
β”œβ”€β”€ prisma/                      # Schema (43 models) + migrations
β”œβ”€β”€ scripts/                     # Background workers + maintenance scripts
β”œβ”€β”€ tests/                       # Playwright E2E suite
β”œβ”€β”€ docs/images/screenshots/     # README screenshots
└── pr-screenshots/              # Historical UI snapshots

πŸ”„ Processing Modes

The app supports three queue back-ends, toggled via QUEUE_BACKEND:

Mode Setting When to use
QStash (default) QUEUE_BACKEND=qstash Production and local dev. Zero-ops async pipeline with retries + signed webhooks. Local dev simulates QStash without an account.
Kafka (on hold) QUEUE_BACKEND=kafka + KAFKA_* vars High-throughput scale-out. Requires the Kafka consumers and WebSocket workers to be running.
Synchronous (legacy) ENABLE_KAFKA_IMAGE_GENERATION=false, no QStash config Debugging only β€” blocks the request until the model finishes.

Multi-model comparison is supported in both async modes via the ComparisonRequest / ComparisonGeneration models.

πŸ§ͺ Testing

  • Unit tests (Vitest 4) β€” colocated as *.test.ts(x). 21+ files across server, services, utils, components, contexts. Run with npm run test.
  • E2E (Playwright) β€” in tests/, 12 specs covering pages, create flows, notifications, streaks, admin audit, sets, video, and the progress toaster. Run with npm run test:e2e.
  • Coverage β€” npm run test:coverage (v8 reporter).

πŸ“š Documentation

Document Purpose
ARCHITECTURE.md High-level system architecture
TECHNICAL_IMPLEMENTATION_GUIDE.md Deep dive into how things are wired up
API.md API endpoint reference
DEVELOPMENT.md Local dev setup
TESTING.md Testing guide
CACHING_STRATEGY.md Redis caching strategy
KAFKA_ENVIRONMENT_SETUP.md Kafka config (when re-enabling)
infrastructure/kafka/README.md Kafka deployment details
CHANGELOG.md Version history
BUGFIXES.md Bug-fix log with root-cause notes
CONTRIBUTING.md Contribution guidelines
IMPROVEMENT_STRATEGY.md Roadmap
REDESIGN_FOLLOWUPS.md Outstanding tasks from PR #150

🀝 Contributing

  1. Fork the repo
  2. Create a feature branch: git checkout -b feat/short-description
  3. npm install and configure .env
  4. Make your change. Run the pre-commit gate:
    npm run lint && npm run typecheck && npm run test:run && npm run build
  5. Add an entry to CHANGELOG.md. If you fixed a notable bug, add a root-cause note to BUGFIXES.md.
  6. Open a PR. Husky + lint-staged will keep your commits clean automatically.

See CONTRIBUTING.md for the long form.

πŸ› Troubleshooting

Database connection errors

echo $DATABASE_URL
npx prisma db push   # also validates the connection

QStash jobs not firing locally

  • Confirm QSTASH_TOKEN and both signing keys are set.
  • Watch the dev server logs for [qstash] lines β€” local dev simulates QStash when keys are absent.

WebSocket connection failures (Kafka mode)

curl -I http://localhost:3001/health
lsof -i :3001

Image generation errors

  • Verify the provider API key for the model you selected (OPENAI_API_KEY, FAL_KEY, etc.).
  • Check S3 permissions for S3_BUCKET_NAME.
  • Look at the request in GenerationLog for the failure reason.

πŸš€ Deployment

Pixel Studio is deployed primarily to Vercel using the @vercel/remix preset. The Express server (server.js) is available for non-Vercel hosts.

Vercel (recommended)

npm i -g vercel
vercel

In the Vercel dashboard:

  • Add every variable from your .env (see env.example).
  • Keep QUEUE_BACKEND=qstash β€” QStash works natively on serverless without long-running workers.

Self-hosted / VPS

Use server.js as the entry point (node server.js) with PM2 or systemd. If you turn Kafka back on, run scripts/startConsumers.ts and scripts/startWebSocketServer.ts as separate services.

Pre-deploy checklist

  • All required env vars present in the target environment
  • DATABASE_URL reachable from the deploy host
  • S3 bucket exists and credentials have PutObject / GetObject permissions
  • Stripe webhook secret matches the configured endpoint
  • QStash signing keys match the dashboard
  • Sentry DSN configured if you want error tracking

πŸ“„ License

MIT β€” see LICENSE.

πŸ™ Acknowledgments

Remix Β· OpenAI Β· Hugging Face Β· Stability AI Β· Runway Β· Luma Β· Tailwind CSS Β· Prisma Β· Radix UI Β· Upstash Β· Vercel


Built with ❀️ by Kevin Reber

About

AI-powered image and video generation platform built with Remix. Generate images using DALL-E, Stable Diffusion, Flux, and more. Create videos with Runway, Luma, and Stability AI. Features collections, social interactions, prompt marketplace, and creator monetization.

Resources

Contributing

Stars

2 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors