A creative workspace that turns a brand profile and a short brief into production-ready marketing visuals, powered by Google Gemini.
π§ Under active development β features and APIs may change between updates. Feedback and contributions are welcome.
The workspace β write a brief on the left, watch on-brand creatives fill the gallery on the right.
AI Creative Studio is an AI-powered design assistant for marketing teams, founders, and creators. You define a brand profile once β name, guidelines, logo β and the studio generates polished, on-brand visuals that respect your look and feel. No design tools, no prompt-engineering expertise required.
Upload a few product shots, describe the campaign, pick an aspect ratio, and generate a full set of ad creatives ready to ship to social, web, or print.
| Feature | Description | |
|---|---|---|
| π·οΈ | Brand Profiles | Save brand name, guidelines, and logo once β every generation stays on-brand. |
| π’ | Ad Creative mode | Turn a campaign brief (goal, copy ideas, product details) into finished ad creatives. |
| πΌοΈ | Asset Generation mode | Generate standalone visual assets from a composition brief, with optional logo + guideline injection. |
| βοΈ | Editor mode | Refine any image with natural-language edit instructions ("remove background", "add neon glow"). |
| π€ | Reference uploads | Add up to 8 product images and 4 style-inspiration images to steer the AI. |
| ποΈ | Per-brand Gallery | Every generated asset is stored and organized by brand. |
| π | Dual environment | Run fully local (SQLite + filesystem) or in the cloud (Supabase DB + Storage). |
| π | Auth-ready | Google OAuth via Supabase, with a one-flag bypass for local development. |
- Social ad campaigns β batch-generate scroll-stopping creatives for Instagram, Facebook, and TikTok.
- Product marketing β turn plain product photos into styled lifestyle and hero shots.
- Brand-consistent content β keep every asset aligned to one set of brand guidelines.
- Rapid concepting β explore visual directions in minutes instead of days.
- Creative editing β iterate on existing assets without reopening a design tool.
| Metric | Value |
|---|---|
| Creative modes | 3 β Ad Creative Β· Asset Gen Β· Editor |
| Aspect ratios | 10 β from 1:1 square to 21:9 ultrawide |
| Max resolution | 4K (1K / 2K / 4K) |
| Assets per batch | Up to 10 |
| Reference inputs | 8 product images + 4 style images |
| Storage backends | 2 β local SQLite or Supabase cloud |
- Frontend: React 18 Β· TypeScript Β· Vite 6
- AI: Google Gemini (
@google/genai) - Backend (local): Express 5 Β· Prisma 7 Β· SQLite
- Backend (cloud): Supabase (PostgreSQL + Storage)
- Node.js (v18 or higher recommended)
- npm or yarn
- Gemini API Key with billing enabled β Get one here
- Supabase Account (optional β only for cloud mode) β Sign up free
β οΈ About the Gemini API key: This app generates images usinggemini-3-pro-image-preview(Nano Banana Pro), which is a Pro tier model. A free-tier key from AI Studio will not work for image generation β free tier only covers Flash models. You'll need a key on a billing-enabled GCP project. Enable billing β
There are two ways to run AI Creative Studio. Pick the one that matches your situation:
| π Local Setup (single machine / personal) | π’ Production Setup (org-wide / team) | |
|---|---|---|
| Who it's for | One person trying it out, or solo development | An agency or team sharing brand profiles + assets |
| Database | SQLite file on your laptop | Supabase Postgres (cloud) |
| Storage | Local storage/ folder |
Supabase Storage bucket |
| Auth | Skipped (BYPASS_AUTH = true) |
Google Sign-In via Supabase, restricted to your team's domain |
| Setup time | ~5 min (one script) | ~20 min (Supabase + Google OAuth + deploy) |
| Cost | Just Gemini API usage | Same + Supabase (free tier covers small teams) |
π Recommended: start with Local Setup to validate it works for you. Moving to Production later is just editing
.env.local+ adding cloud credentials β no code changes.
The fastest path β an interactive setup script that handles everything: prompts for your Gemini key, installs dependencies, runs migrations, creates the storage folder, and starts the dev server. Re-running is safe β already-done steps are skipped.
bash setup.shpowershell -ExecutionPolicy Bypass -File setup.ps1π New here? Just run the script. It defaults to local mode (SQLite + filesystem) so no Supabase or Google OAuth needed to try it out. It also tells you what each value is for β including the Gemini billing requirement β before asking.
When it's done, your browser opens to http://localhost:3000.
What the script does (step-by-step)
| Step | What it checks / does |
|---|---|
| 1 | Verifies you're in the project root (package.json) |
| 2 | Verifies Node.js v18+ is installed (links to download if not) |
| 3 | Creates .env.local from .env.example if missing |
| 4 | Prompts for your Gemini API key β with a note about free vs paid tier (Pro Image model needs billing enabled) |
| 5 | Asks local vs cloud mode; if cloud, prompts for Supabase URL + anon key |
| 6 | Runs npm install if node_modules is missing or stale |
| 7 | Runs prisma migrate deploy to create dev.db (local mode only) |
| 8 | Creates storage/creatives/ folder for asset uploads (local mode only) |
| 9 | Starts the dev server (npm run dev or npm run dev:prod) |
The script validates input format (Gemini key starts with AIza, Supabase URL matches *.supabase.co, anon key is a JWT) so typos are caught before they break the app.
Manual setup (if you prefer to do it by hand)
# 1. Install dependencies
npm install
# 2. Copy environment template
cp .env.example .env.local
# 3. Add your GEMINI_API_KEY in .env.local
# (Supabase keys are optional β only needed for cloud mode)
# 4. Run database migrations (local mode)
DATABASE_URL="file:./dev.db" npx prisma migrate deploy
# 5. Run the app
npm run devOpen http://localhost:3000 in your browser.
Use this path when you want your whole agency/team to share brand profiles, gallery assets, and sign in with their work Google account.
You'll wire up three things (~20 min total):
-
ποΈ Supabase project β hosts the Postgres DB and the asset storage bucket. β Follow Supabase Setup below (create project, run SQL, create
creativesbucket). -
π Google OAuth via Supabase β so only your team's email domain can sign in. β Follow GOOGLE_AUTH_SETUP.md (10-min walkthrough with screenshots).
-
π Production-mode toggle β switch the app from "bypass auth, local DB" to "require Google, cloud DB":
- In
.env.local: setAPP_ENV=productionand fill inSUPABASE_URL+SUPABASE_ANON_KEY - In
App.tsx: setBYPASS_AUTH = falseand changeALLOWED_DOMAINto your team's domain - Run
npm run dev:prod(or deploy the built app to any host β Vercel, Render, etc.)
- In
π‘ The setup script also handles Production mode. If your
.env.localalready hasAPP_ENV=production,setup.sh/setup.ps1will prompt for your Supabase credentials and start the cloud-mode dev server.
π¦ One-click cloud deploy (Vercel/Supabase integration) is on the roadmap β for now, deploy the
npm run buildoutput to any static host that runs Node.
π‘ The setup script writes this file for you. This section is here for reference β read it if you want to know what each variable does or edit
.env.localby hand.
-
Copy the template file:
cp .env.example .env.local
-
Edit
.env.localwith your credentials:# Gemini API Key (Required) GEMINI_API_KEY=your_actual_gemini_api_key # Supabase Credentials (Required for cloud features) SUPABASE_URL=https://your-project-id.supabase.co SUPABASE_ANON_KEY=your_supabase_anon_key
β οΈ Important: Never commit.env.localto version control!
The app supports Google Sign-In via Supabase, with a one-flag bypass for local development.
const BYPASS_AUTH = true; // dev: skip login, mock session
const ALLOWED_DOMAIN = 'yourdomain.com'; // prod: only this email domain can sign in| Value | Behavior |
|---|---|
BYPASS_AUTH = true |
β Auth skipped β app loads immediately (good for local dev) |
BYPASS_AUTH = false |
π Requires Google Sign-In; only @ALLOWED_DOMAIN emails are accepted |
β οΈ Before flipping tofalse, changeALLOWED_DOMAINaway from the default'yourdomain.com'β otherwise no one will be able to sign in.
To make BYPASS_AUTH = false actually work, you need to wire up Google OAuth in both Supabase and Google Cloud. Follow the step-by-step guide:
π GOOGLE_AUTH_SETUP.md β 10-minute walkthrough with screenshots
It covers: grabbing the Supabase callback URL, creating the Google Cloud OAuth app, where to paste the Authorized redirect URI, restricting access to your Workspace org, and troubleshooting.
Only needed for Production / Org-wide setup. For Local Setup, the app uses SQLite and local file storage out of the box β see DEVELOPMENT.md.
- Go to supabase.com and sign in
- Click "New Project"
- Fill in:
- Name:
creative-studio(or any name) - Database Password: Create a strong password (save it!)
- Region: Choose closest to your users
- Name:
- Click "Create new project"
- Wait for project to initialize (1-2 minutes)
- In your Supabase dashboard, go to Project Settings (gear icon)
- Click API in the left sidebar
- Copy these values to your
.env.local:- Project URL β
SUPABASE_URL - anon/public key β
SUPABASE_ANON_KEY
- Project URL β
Example:
SUPABASE_URL=https://abcdefghijklmnop.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...- In Supabase dashboard, go to Storage (left sidebar)
- Click "New bucket"
- Enter:
- Name:
creatives - Public bucket: β Enable (toggle ON)
- Name:
- Click "Create bucket"
π‘ The bucket name must be exactly
creativesto match the app code.
- In Supabase dashboard, go to SQL Editor (left sidebar)
- Click "New query"
- Copy and paste the ENTIRE SQL script below
- Click "Run" (or press Ctrl/Cmd + Enter)
π Click to expand the complete SQL setup script
-- ===========================================
-- AI CREATIVE STUDIO - DATABASE SETUP
-- ===========================================
-- Run this entire script in Supabase SQL Editor
-- This will create all tables, policies, and storage setup
-- ===========================================
-- STEP 1: CREATE TABLES
-- ===========================================
-- Brand Profiles Table
CREATE TABLE IF NOT EXISTS brand_profiles (
id TEXT PRIMARY KEY,
name TEXT,
guidelines TEXT,
logo_preview TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW())
);
-- Generated Assets Table
CREATE TABLE IF NOT EXISTS generated_assets (
id TEXT PRIMARY KEY,
profile_id TEXT NOT NULL,
url TEXT NOT NULL,
prompt_used TEXT,
aspect_ratio TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT TIMEZONE('utc'::TEXT, NOW())
);
-- ===========================================
-- STEP 2: ENABLE ROW LEVEL SECURITY (RLS)
-- ===========================================
-- Enable RLS on brand_profiles
ALTER TABLE brand_profiles ENABLE ROW LEVEL SECURITY;
-- Enable RLS on generated_assets
ALTER TABLE generated_assets ENABLE ROW LEVEL SECURITY;
-- ===========================================
-- STEP 3: CREATE ACCESS POLICIES
-- ===========================================
-- These policies allow public CRUD access (suitable for development/internal tools)
-- For production with user accounts, you'd want more restrictive policies
-- Drop existing policies if they exist (prevents errors on re-run)
DROP POLICY IF EXISTS "Public Profiles Access" ON brand_profiles;
DROP POLICY IF EXISTS "Public Assets Access" ON generated_assets;
-- Allow full public access to brand_profiles (SELECT, INSERT, UPDATE, DELETE)
CREATE POLICY "Public Profiles Access" ON brand_profiles
FOR ALL
USING (true)
WITH CHECK (true);
-- Allow full public access to generated_assets (SELECT, INSERT, UPDATE, DELETE)
CREATE POLICY "Public Assets Access" ON generated_assets
FOR ALL
USING (true)
WITH CHECK (true);
-- ===========================================
-- STEP 4: SETUP STORAGE BUCKET
-- ===========================================
-- Create the 'creatives' bucket if it doesn't exist
INSERT INTO storage.buckets (id, name, public)
VALUES ('creatives', 'creatives', true)
ON CONFLICT (id) DO NOTHING;
-- ===========================================
-- STEP 5: STORAGE POLICIES
-- ===========================================
-- Drop existing storage policies if they exist
DROP POLICY IF EXISTS "Public Uploads" ON storage.objects;
DROP POLICY IF EXISTS "Public Reads" ON storage.objects;
DROP POLICY IF EXISTS "Public Deletes" ON storage.objects;
-- Allow public uploads to 'creatives' bucket
CREATE POLICY "Public Uploads" ON storage.objects
FOR INSERT
WITH CHECK (bucket_id = 'creatives');
-- Allow public reads from 'creatives' bucket
CREATE POLICY "Public Reads" ON storage.objects
FOR SELECT
USING (bucket_id = 'creatives');
-- Allow public deletes from 'creatives' bucket
CREATE POLICY "Public Deletes" ON storage.objects
FOR DELETE
USING (bucket_id = 'creatives');
-- ===========================================
-- β
SETUP COMPLETE!
-- ===========================================
-- Your database is now ready for AI Creative Studionpm run devOpens at http://localhost:3000
npm run build
npm run previewFor the full local development guide (dual environments, scripts, database management, API endpoints), see DEVELOPMENT.md.
- Check that
SUPABASE_URLandSUPABASE_ANON_KEYare set correctly in.env.local - Restart the dev server after changing environment variables
- Make sure you ran the complete SQL setup script
- Check that RLS policies were created successfully in Supabase Dashboard > Authentication > Policies
- Verify the
creativesstorage bucket exists and is public - Check storage policies in Supabase Dashboard > Storage > Policies
- Ensure
BYPASS_AUTH = falseandALLOWED_DOMAINis set correctly inApp.tsx - Follow the full step-by-step in GOOGLE_AUTH_SETUP.md β it covers Supabase + Google Cloud config and the most common
redirect_uri_mismatchfix
If you see errors about process not being found, run:
npm installThese are dev-time warnings and won't affect runtime.
Released under the MIT License β free to use, modify, and distribute. Just keep the copyright notice.
Owner: Arcady Media Inc.
Developer: Ritik
- Gemini API Keys: https://aistudio.google.com/app/apikey
- Supabase: https://supabase.com
- Development Guide: DEVELOPMENT.md



