Skip to content

About

AI-powered end-to-end creative platform

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

Blue Fish

Blue Fish

English | 简体中文

An open-source AI storyboard & video generation studio. Go from script -> storyboard -> generated video in a single web UI, across major AI providers.

License Python Node FastAPI React PRs Welcome


Join the Blue Fish Community

Get updates, ask questions, and share what you are building with Blue Fish.

Join Discord Follow on X

Direct contact: mantaxyz2025@gmail.com
Rednote / 小红书: Manta
Manta Xiaohongshu QR code


Blue Fish is a self-hostable studio that turns written ideas into complete video sequences. It bundles a React front end and a FastAPI back end together, and adapts multiple LLM, image, and video generation providers, so you can switch models, compare results, and keep the whole workflow inside one app.

Out of the box it runs with zero infrastructure: one JSON file for persistence, the local filesystem for media, and a mock mode that lets you experience the full UI without any paid API keys.

Table of Contents

Features

Creative

  • 🎬 Storyboard generation - text-to-image, image-to-image, and frame-to-frame with reference consistency
  • 🎥 Multiple video providers - Kling, Seedance, Runway, Vidu, DashScope, Replicate, Google Veo
  • 👤 Character and scene management, with visual references reused across scenes
  • ✍️ Script and dialogue generation - powered by Gemini and OpenAI
  • 🔊 Text-to-speech - powered by ElevenLabs
  • 🎞️ Video editing - captions, sound effects, and music generation are wired into the timeline

Developer-friendly

  • 💾 Zero-config persistence - JSON file storage with no Postgres, Redis, or similar services to configure
  • 🧪 Mock mode - run the full UI without any paid API keys
  • 🌏 Bilingual UI - English and Simplified Chinese (src/i18n/zhToEnMap.js)
  • 🐳 Docker Compose - bring up the front end and back end together with one command
  • 🧩 Provider adapter pattern - add a new video model by implementing one interface

Product Preview

Style Settings Character Gallery
Blue Fish style settings screen Blue Fish character gallery screen
Storyboard Management Video Generation
Blue Fish storyboard management screen Blue Fish video generation screen

Quick Start

⚠️ Security note: the default first-login credentials are admin / admin123. Change AUTH_BOOTSTRAP_ADMIN_PASSWORD before exposing the backend publicly. See Security.

Option 1 - Docker (recommended)

git clone <your-fork-url> bluefish
cd bluefish
cp bluefish-server/.env.example bluefish-server/.env
cp bluefish-client/.env.example bluefish-client/.env.local
docker compose up

If you edit an env file later, restart the matching service so the change takes effect:

docker compose up -d --force-recreate backend
docker compose up -d --force-recreate frontend

The copied example env lets you sign in locally with:

username: admin
password: admin123

Before exposing the backend publicly, edit bluefish-server/.env and set at least:

AUTH_BOOTSTRAP_ADMIN_PASSWORD=choose-a-password
# optional: allow users to create their own accounts
# AUTH_ALLOW_REGISTRATION=true

Open http://localhost:5173 and sign in with admin plus the bootstrap admin password from bluefish-server/.env or the backend startup logs. By default, Blue Fish runs in a single-admin self-hosted mode. The public register page stays hidden unless you explicitly set AUTH_ALLOW_REGISTRATION=true. New accounts and password changes require at least 8 characters by default.

For VIDU, Kling, and Seedance, Blue Fish enables a Cloudflare Quick Tunnel by default. The default .env.example keeps autostart off, so the tunnel is created only when one of those providers actually needs a public temp-asset URL.

Option 2 - Manual install

Prerequisites: Node.js 20+, Python 3.11+, and ffmpeg on PATH.

# Backend (terminal 1)
cd bluefish-server
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
uvicorn app.main:app --reload --port 8000

# Frontend (terminal 2)
cd bluefish-client
npm install
cp .env.example .env.local
npm run dev

Option 3 - No API keys (mock mode)

Run the full UI against fake providers - useful for demos, UI work, and exploration.

# bluefish-server/.env
LLM_MOCK_MODE=true
VIDEO_MOCK_MODE=true

Configuration

All configuration is driven by environment files:

File Purpose
bluefish-server/.env API keys, storage paths, feature flags
bluefish-client/.env.local Front-end build-time config (API URL, flags)

These files are loaded on process start. After changing one, restart the matching service.

Auth

Variable Default Purpose
AUTH_BOOTSTRAP_ADMIN_PASSWORD admin123 Initial password for the bootstrap admin user. It only applies when the first admin user is created
AUTH_ALLOW_REGISTRATION false Show the public register page and allow self-service sign-up
AUTH_MIN_PASSWORD_LENGTH 8 Minimum password length for registration and password changes. Values below 8 are ignored
AUTH_TOKEN_TTL_SECONDS 604800 Bearer token lifetime (seconds)

LLM providers (configure at least one)

Variable Provider Notes
GEMINI_API_KEY Google AI Studio Free tier available
GPT_API_KEY OpenAI

Video providers (all optional, enable what you need)

Provider Variables
Kling KLING_ACCESS_KEY, KLING_SECRET_KEY
Seedance (Volcengine) SEEDANCE_API_KEY
Runway RUNWAY_API_KEY
Vidu VIDU_API_KEY
DashScope (Alibaba) ALI_API_KEY
Replicate REPLICATE_API_TOKEN
Google Veo reuses GEMINI_API_KEY

Feature flags (optional)

Variable Default Purpose
ENABLE_EDITED_VIDEOS false Enable the edited-videos timeline module

Text-to-speech (optional)

Variable Provider
ELEVENLABS_API_KEY ElevenLabs

Upload limits (optional)

Variable Default Purpose
MAX_IMAGE_UPLOAD_MB 10 Max size for image uploads
MAX_AUDIO_UPLOAD_MB 50 Max size for transcription uploads
MAX_DOCUMENT_UPLOAD_MB 20 Max size for PDF / DOCX parsing
MAX_EDITED_VIDEO_UPLOAD_MB 250 Max size for edited video uploads
MAX_ADMIN_IMPORT_UPLOAD_MB 1 Max size for admin JSON imports

Video Provider Network Setup

Blue Fish stores frames and generated media on the local filesystem. Different providers consume those assets in different ways:

  • Runway supports inline image data, so it does not need a public URL.
  • VIDU, Kling, and Seedance fetch source images by URL. Blue Fish issues short-lived, signed /api/temp-assets/<token> URLs. If you enable the built-in Cloudflare Quick Tunnel, Blue Fish publishes only /api/temp-assets/* and /health on the generated public host. The local frontend still loads raw media from http://localhost:8000/uploads/* on your machine; those local-only paths are not exposed through the built-in Quick Tunnel.

If you only use Runway, no extra setup is required. If you use VIDU, Kling, or Seedance, you can either enable the built-in Quick Tunnel or configure your own stable public hostname via PUBLIC_MEDIA_BASE_URL.

Backend variables

LOCAL_STORAGE_URL_BASE=http://localhost:8000/uploads
PUBLIC_MEDIA_BASE_URL=                               # Optional stable public HTTPS base URL of the backend
TEMP_ASSET_TTL_SECONDS=900
TEMP_ASSET_SIGNING_SECRET=replace-this-with-a-random-secret

PUBLIC_MEDIA_BASE_URL is optional in the default setup. When it is empty and FREE_TUNNEL_ENABLED=true, Blue Fish will start a Quick Tunnel and inject a temporary public base URL at runtime the first time a provider needs it. If you set PUBLIC_MEDIA_BASE_URL manually, Blue Fish will reuse it and skip creating a Quick Tunnel as long as the URL stays healthy.

Free dev tunnel mode

For local development and open-source self-hosting, Blue Fish can optionally manage a Cloudflare Quick Tunnel for you:

FREE_TUNNEL_ENABLED=true
FREE_TUNNEL_AUTOSTART=false
FREE_TUNNEL_LOCAL_PORT=8000
FREE_TUNNEL_HEALTHCHECK_PATH=/health

With the default FREE_TUNNEL_AUTOSTART=false, Blue Fish lazily creates the tunnel only when VIDU, Kling, or Seedance first needs a public temp-asset URL. Before each such task, Blue Fish checks whether the current public URL is reachable. If it is not, Blue Fish automatically rebuilds the tunnel once. Quick Tunnel URLs are temporary and may change every time the app starts. This mode is ideal for local testing and self-hosted evaluation, but not for long-lived production deployments.

Example: Cloudflare Tunnel

  1. Create a tunnel that maps https://media.example.com -> http://localhost:8000.
  2. Set PUBLIC_MEDIA_BASE_URL=https://media.example.com in bluefish-server/.env.
  3. Restart the backend. Blue Fish will hand providers short-lived URLs like https://media.example.com/api/temp-assets/<token>.
  4. In the tunnel or reverse-proxy config, forward only /api/temp-assets/*, the /api/* endpoints your providers need, and /health - do not forward /uploads/* or /ws publicly unless you have added authentication.

Verification

  1. GET https://your-public-host/health should return {"status":"ok"}.
  2. Start one video task with VIDU, Kling, or Seedance.
  3. If PUBLIC_MEDIA_BASE_URL is missing or unreachable, the backend returns a clear error before the task is sent to the provider.

Architecture

┌─────────────┐        HTTP / WebSocket       ┌─────────────┐
│   React 19  │ ─────────────────────────────>│   FastAPI   │
│     Vite    │ <───────────────────────────── │  (uvicorn)  │
│  Tailwind   │                                └──────┬──────┘
└─────────────┘                                       │
                        ┌──────────────────┬──────────┴────────┬────────────────┐
                        ▼                  ▼                   ▼                ▼
                   ┌────────┐         ┌─────────┐         ┌─────────┐      ┌─────────┐
                   │  LLM   │         │  Video  │         │   TTS   │      │ Storage │
                   │ Gemini │         │  Kling  │         │ Eleven- │      │  JSON   │
                   │ OpenAI │         │ Runway… │         │  Labs   │      │ + files │
                   └────────┘         └─────────┘         └─────────┘      └─────────┘
  • Persistence - bluefish-server/bluefish.db.json stores all project data. Replace or clear it to reset.
  • Media - uploaded and generated assets are stored under bluefish-server/uploads/.
  • Real-time - long-running tasks (video generation) stream progress to the frontend over WebSocket.
  • Provider adapters - each video or LLM provider is isolated under app/services/<provider>_service.py.

Project Structure

.
├── bluefish-client/           # React 19 + Vite + Tailwind front end
│   ├── src/
│   │   ├── pages/             # Route pages (Projects, Storyboards, Videos...)
│   │   ├── components/        # Reusable UI (layout, credits, admin...)
│   │   ├── contexts/          # React contexts (WebSocket, auth)
│   │   ├── stores/            # Zustand stores
│   │   ├── api/               # Typed API client
│   │   ├── services/          # Browser-side service wrappers
│   │   ├── hooks/             # Reusable React hooks
│   │   ├── core/              # Cross-cutting domain logic
│   │   ├── lib/               # Third-party helpers and adapters
│   │   ├── utils/             # Frontend utilities (logging, downloads, navigation)
│   │   ├── constants/         # Shared constants
│   │   ├── assets/            # Static assets
│   │   ├── test/              # vitest setup and utilities
│   │   └── i18n/              # Chinese-English translation map
│   └── vite.config.js
├── bluefish-server/           # FastAPI back end
│   ├── app/
│   │   ├── main.py            # FastAPI entrypoint
│   │   ├── models.py          # Pydantic schemas
│   │   ├── routes/            # HTTP routes (auth, projects, storyboards,
│   │   │                      #   generation, temp_assets, music_generation...)
│   │   ├── services/          # Provider adapters (Kling, Runway, Vidu,
│   │   │                      #   google_genai, elevenlabs...)
│   │   ├── auth/              # Auth dependencies and token handling
│   │   ├── middleware/        # Request middleware
│   │   ├── constants/         # Model catalogs and enums
│   │   ├── db/                # JSON repository layer
│   │   └── utils/             # S3, temp-asset, cost-estimator helpers
│   ├── scripts/               # Maintenance scripts
│   ├── tests/                 # pytest suite
│   ├── application.py         # ASGI application entrypoint
│   ├── check_dependencies.py  # Import-check helper
│   └── requirements.txt
├── docs/                      # Project documentation and assets
├── .github/                   # GitHub Actions workflows and templates
├── docker-compose.yml
├── CHANGELOG.md
├── LICENSE                    # Apache 2.0
├── TRADEMARK.md               # Trademark terms for forks
├── SECURITY.md                # Vulnerability reporting process
├── CONTRIBUTING.md
└── CODE_OF_CONDUCT.md

Development

Backend

cd bluefish-server
pytest tests -q                     # Unit tests
pytest tests -q -m "not slow"       # Fast subset (matches CI)
python check_dependencies.py        # Verify dependencies can be imported

Frontend

cd bluefish-client
npm run dev            # Dev server on :5173
npm run lint           # eslint
npm run test           # vitest (watch)
npm run test:ci        # vitest run
npm run build          # Production build -> dist/

Docker dev

The bundled Dockerfile.dev files are meant for hot-reload development. For production, build an image without --reload and run it as a non-root user.

The backend Dockerfile.dev now installs a pinned cloudflared binary by default so the built-in Quick Tunnel works out of the box in the dev container. The version and SHA-256 remain explicit build args so the image stays reproducible instead of pulling latest.

CI

GitHub Actions run on every PR targeting main, develop, and new-ui - see .github/workflows/pr-ci.yml. A nightly regression workflow runs the full suite, including slow-marked tests.

Security

  • Bootstrap admin password. Blue Fish uses admin/admin123 for a friction-free first local login. Change AUTH_BOOTSTRAP_ADMIN_PASSWORD before any shared or public deployment. This value only applies when the first admin user is created; after a user changes the password, the existing users.json password is kept. Auth tokens also expire (AUTH_TOKEN_TTL_SECONDS, default 7 days).
  • Password policy. Blue Fish enforces a minimum password length of 8 characters even if AUTH_MIN_PASSWORD_LENGTH is set lower. The frontend reads this policy from /api/auth/config, so the register form and backend stay aligned.
  • Registration. Self-service registration is disabled by default, and the frontend hides the register page unless AUTH_ALLOW_REGISTRATION=true. This keeps the default open-source/self-host workflow in a clean single-admin mode.
  • Media access model. /uploads/* is mounted as an unauthenticated static directory so the local frontend can load images and videos directly. The built-in Quick Tunnel does not expose /uploads/*, /ws, or the rest of the API — it only allows /api/temp-assets/* and /health. If you expose the backend through your own stable tunnel, reverse proxy, or direct bind, restrict /uploads/* at that layer - forward only /api/temp-assets/*, /api/*, and /health. Signed temp-asset tokens (TEMP_ASSET_SIGNING_SECRET) protect only the URLs handed to providers; they do not protect the raw static mount.
  • Signing secret. Before exposing the backend to the public internet, set TEMP_ASSET_SIGNING_SECRET to a long random string. The default value is a process-scoped random value, which is sufficient for local development but becomes invalid across restarts.
  • API keys. Never commit .env files. The repository already ignores them by default. .env.example is the single source of truth for the variable list.
  • Open-source release hygiene. If this project has ever been used with real provider keys in a private repo, rotate those keys before publishing. .gitignore protects future commits, not secrets that may already exist in git history, screenshots, or copied docs.

Troubleshooting

Port 8000 or 5173 already in use

lsof -ti:8000,5173 | xargs kill -9

ffmpeg: command not found

brew install ffmpeg                     # macOS
sudo apt-get install -y ffmpeg          # Ubuntu / Debian

Video provider returns 502 Bad Gateway / resource download failed The provider could not fetch the temporary source image. Check PUBLIC_MEDIA_BASE_URL, or let the automatic Quick Tunnel rebuild and retry.

Seedance returns 400 Bad Request - "input image may contain real person" The provider's content policy rejected the request. Regenerate the source frame.

Mock mode not taking effect Confirm that LLM_MOCK_MODE=true and/or VIDEO_MOCK_MODE=true are set in bluefish-server/.env, then restart the backend.

Contributing

Pull requests are welcome. Before opening one:

  1. Read CONTRIBUTING.md to understand the workflow and commit conventions.
  2. Read CODE_OF_CONDUCT.md.
  3. Make sure pytest and npm run test:ci pass locally.

Translations, new provider adapters, and documentation improvements are especially welcome. For direct collaboration or product questions, contact mantaxyz2025@gmail.com.

Acknowledgments

Blue Fish stands on the shoulders of many open-source projects, including:

Star History

Star History Chart

License & Trademark

Source code is released under the Apache License 2.0.

The name Blue Fish and its branding are trademarks - see TRADEMARK.md for usage terms on forks and derived works.

About

AI-powered end-to-end creative platform

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages