Skip to content

Latest commit

Β 

History

4 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

AI Creative Studio logo

🎨 AI Creative Studio

Generate on-brand ad creatives & visual assets with AI β€” in seconds.

A creative workspace that turns a brand profile and a short brief into production-ready marketing visuals, powered by Google Gemini.

Status License React TypeScript Vite Gemini

🚧 Under active development β€” features and APIs may change between updates. Feedback and contributions are welcome.

AI Creative Studio workspace

The workspace β€” write a brief on the left, watch on-brand creatives fill the gallery on the right.


✨ What is it?

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.


πŸš€ Features

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.

🎯 What you can use it for

  • 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.

πŸ“Š At a glance

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

πŸ“Έ Screenshots

Visual asset uploads and aspect ratios
Visual Assets β€” upload product shots & style inspiration, pick from 10 aspect ratios.
New Brand Profile form
Brand Profiles β€” define name, guidelines, and logo once.
Asset Generation mode
Asset Gen β€” generate visuals from a composition brief.
Editor mode
Editor β€” refine any image with natural-language instructions.

🧰 Tech Stack

  • Frontend: React 18 Β· TypeScript Β· Vite 6
  • AI: Google Gemini (@google/genai)
  • Backend (local): Express 5 Β· Prisma 7 Β· SQLite
  • Backend (cloud): Supabase (PostgreSQL + Storage)

πŸ“‹ Prerequisites

  • Node.js 20.19+, 22.12+, or 24+ (22 LTS recommended). Prisma 7 and the Vite React plugin will not run on Node 18, and 20.11 is not enough either.
  • 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 using gemini-3-pro-image (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 β†’ Image generation is billed per image, and a batch of 10 costs 10 images' worth, so check current pricing before running large batches.

πŸ”‘ Where your key ends up: the app calls Gemini from the browser, so npm run build compiles GEMINI_API_KEY into the JavaScript it ships. Anyone who can load a deployed build can read it. Keep deployments private, or run locally, until generation moves behind a server.


βš™οΈ Setup β€” Pick Your Path

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 (APP_ENV=development) Google Sign-In via Supabase (APP_ENV=production), optionally restricted to one email 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 a .env.local change only: set APP_ENV=production and add your Supabase credentials. Authentication switches on automatically. No source files to edit.


🏠 Quick Start β€” Local Setup (single machine)

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.

macOS / Linux

git clone https://github.com/Arcady-Inc/ai-creative-studio.git
cd ai-creative-studio
bash setup.sh

Windows (PowerShell)

git clone https://github.com/Arcady-Inc/ai-creative-studio.git
cd ai-creative-studio
powershell -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 it starts the dev server. Open 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 20.19+/22.12+/24+ 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 (Supabase URL matches *.supabase.co; the Supabase key is a eyJ... JWT or a sb_publishable_... key; the Gemini key is a plausible key string) so typos are caught before they break the app.

Manual setup (if you prefer to do it by hand)

macOS / Linux

git clone https://github.com/Arcady-Inc/ai-creative-studio.git
cd ai-creative-studio
npm install
cp .env.example .env.local
# Add your GEMINI_API_KEY to .env.local
# (Supabase keys are optional, only needed for cloud mode)
npx prisma migrate deploy   # creates dev.db
npx prisma generate         # required: the server imports the generated client
npm run dev

Windows (PowerShell)

git clone https://github.com/Arcady-Inc/ai-creative-studio.git
cd ai-creative-studio
npm install
Copy-Item .env.example .env.local
# Add your GEMINI_API_KEY to .env.local
npx prisma migrate deploy
npx prisma generate
npm run dev

Do not skip npx prisma generate. Without it server/dev-server.ts fails to import @prisma/client and the API server exits immediately.

Open http://localhost:3000 in your browser.


🏒 Production Setup β€” Organization-Wide (team / cloud)

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):

  1. πŸ—„οΈ Supabase project β€” hosts the Postgres DB and the asset storage bucket. β†’ Follow the Supabase Setup section below (create project, run SQL, create the creatives bucket).

  2. πŸ” Google OAuth via Supabase β€” so only your team's email domain can sign in. β†’ Follow GOOGLE_AUTH_SETUP.md (10-min walkthrough with screenshots).

  3. πŸš€ Production-mode toggle β€” switch the app from "bypass auth, local DB" to "require Google, cloud DB":

    • In .env.local: set APP_ENV=production and fill in SUPABASE_URL + SUPABASE_ANON_KEY
    • In .env.local: optionally set ALLOWED_DOMAIN to your team's email domain
    • Run npm run dev:prod (or deploy the built app to any host β€” Vercel, Render, etc.)

πŸ’‘ The setup script also handles Production mode. If your Supabase credentials are missing, setup.sh / setup.ps1 offers to collect them and sets APP_ENV=production for you. If you decline and APP_ENV is already production, the script leaves it alone and tells you what is still missing.

πŸ“¦ Hosting is not documented yet, on purpose. npm run build produces a static bundle with your Gemini API key compiled into it, so we are not going to tell you to upload that to a public host. Generation is being moved behind a server; deployment guides (Docker, Vercel, and a one-click option) land with it. Until then, run it locally, or host it somewhere only your team can reach.

The design for that work, including support for OpenAI, FLUX and OpenRouter alongside Gemini, is in docs/design/multi-provider-image-models.md.


πŸ”§ Environment Setup (reference for both paths)

πŸ’‘ 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.local by hand.

  1. Copy the template file:

    cp .env.example .env.local
  2. Edit .env.local with 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.local to version control!


πŸ” Authentication (skipped in Local; required in Production)

The app supports Google Sign-In via Supabase, with a one-flag bypass for local development.

Controlled by .env.local, not by editing source

APP_ENV=development     # sign-in skipped
APP_ENV=production      # Google sign-in required

ALLOWED_DOMAIN=yourcompany.com   # optional: only @yourcompany.com can sign in
APP_ENV Behavior
development Auth skipped, app loads immediately. Local SQLite + filesystem.
production Google Sign-In required via Supabase. Cloud DB + storage.

ALLOWED_DOMAIN is optional. Set it to example.com to accept only @example.com accounts; leave it empty to accept any Google account that signs in.

⚠️ This is a client-side check. It controls what the UI renders, not what the database allows. A user outside your domain still holds a valid Supabase token after signing in, so enforce the real restriction in your RLS policies too.

Setting up Google Sign-In (production)

To make APP_ENV=production sign-in 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.


πŸ—„οΈ Supabase Setup (Production / Org-wide path only)

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.

1. Create Supabase Project

  1. Go to supabase.com and sign in
  2. Click "New Project"
  3. Fill in:
    • Name: creative-studio (or any name)
    • Database Password: Create a strong password (save it!)
    • Region: Choose closest to your users
  4. Click "Create new project"
  5. Wait for project to initialize (1-2 minutes)

2. Get Project Credentials

  1. In your Supabase dashboard, go to Project Settings (gear icon)
  2. Click API in the left sidebar
  3. Copy these values to your .env.local:
    • Project URL β†’ SUPABASE_URL
    • anon/public key β†’ SUPABASE_ANON_KEY

Example:

SUPABASE_URL=https://abcdefghijklmnop.supabase.co
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

3. Create Storage Bucket

  1. In Supabase dashboard, go to Storage (left sidebar)
  2. Click "New bucket"
  3. Enter:
    • Name: creatives
    • Public bucket: βœ… Enable (toggle ON)
  4. Click "Create bucket"

πŸ’‘ The bucket name must be exactly creatives to match the app code.

4. Run SQL Setup

  1. In Supabase dashboard, go to SQL Editor (left sidebar)
  2. Click "New query"
  3. Copy and paste the ENTIRE SQL script below
  4. 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 grant access to SIGNED-IN users only.
--
-- Do not use `USING (true)` without a TO clause here. Postgres defaults such a
-- policy to TO PUBLIC, which includes the `anon` role, and the anon key is
-- readable by anyone who loads the app. That combination lets an unauthenticated
-- caller read, modify and delete every brand profile and asset straight through
-- the REST API, bypassing the login screen entirely.

-- Drop old permissive policies if a previous version of this script ran
DROP POLICY IF EXISTS "Public Profiles Access" ON brand_profiles;
DROP POLICY IF EXISTS "Public Assets Access" ON generated_assets;
DROP POLICY IF EXISTS "Authenticated Profiles Access" ON brand_profiles;
DROP POLICY IF EXISTS "Authenticated Assets Access" ON generated_assets;

-- Signed-in users can read and write brand profiles
CREATE POLICY "Authenticated Profiles Access" ON brand_profiles
  FOR ALL
  TO authenticated
  USING (true)
  WITH CHECK (true);

-- Signed-in users can read and write generated assets
CREATE POLICY "Authenticated Assets Access" ON generated_assets
  FOR ALL
  TO authenticated
  USING (true)
  WITH CHECK (true);

-- OPTIONAL: restrict to one Google Workspace domain, enforced in the database
-- rather than the browser. Replace both policies above with these, substituting
-- your domain. This is the enforcement that ALLOWED_DOMAIN in the UI cannot provide.
--
-- DROP POLICY IF EXISTS "Authenticated Profiles Access" ON brand_profiles;
-- CREATE POLICY "Domain Profiles Access" ON brand_profiles
--   FOR ALL TO authenticated
--   USING      ((auth.jwt() ->> 'email') LIKE '%@yourcompany.com')
--   WITH CHECK ((auth.jwt() ->> 'email') LIKE '%@yourcompany.com');
--
-- DROP POLICY IF EXISTS "Authenticated Assets Access" ON generated_assets;
-- CREATE POLICY "Domain Assets Access" ON generated_assets
--   FOR ALL TO authenticated
--   USING      ((auth.jwt() ->> 'email') LIKE '%@yourcompany.com')
--   WITH CHECK ((auth.jwt() ->> 'email') LIKE '%@yourcompany.com');

-- ===========================================
-- 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;
DROP POLICY IF EXISTS "Authenticated Uploads" ON storage.objects;
DROP POLICY IF EXISTS "Authenticated Deletes" ON storage.objects;

-- Only signed-in users can upload
CREATE POLICY "Authenticated Uploads" ON storage.objects
  FOR INSERT
  TO authenticated
  WITH CHECK (bucket_id = 'creatives');

-- Only signed-in users can delete
CREATE POLICY "Authenticated Deletes" ON storage.objects
  FOR DELETE
  TO authenticated
  USING (bucket_id = 'creatives');

-- Reads stay public because the app displays images via getPublicUrl().
--
-- Know what this means: every generated creative is readable by anyone with the
-- URL, forever, with no login. For client work under NDA that is usually not
-- acceptable. Making the bucket private requires switching
-- services/db/supabase.ts from getPublicUrl() to createSignedUrl(); that change
-- is tracked with the server-side generation work.
CREATE POLICY "Public Reads" ON storage.objects
  FOR SELECT
  USING (bucket_id = 'creatives');

-- ===========================================
-- βœ… SETUP COMPLETE!
-- ===========================================
-- Your database is now ready for AI Creative Studio

▢️ Running the App

Development Mode

npm run dev

Opens at http://localhost:3000

Production Build

npm run build
npm run preview

For the full local development guide (dual environments, scripts, database management, API endpoints), see DEVELOPMENT.md.


πŸ› Troubleshooting

"Database not connected" Error

  • Check that SUPABASE_URL and SUPABASE_ANON_KEY are set correctly in .env.local
  • Restart the dev server after changing environment variables

"RLS policy" or "Permission denied" Errors

  • Make sure you ran the complete SQL setup script
  • Check that RLS policies were created successfully in Supabase Dashboard > Authentication > Policies

Images not uploading

  • Verify the creatives storage bucket exists and is public
  • Check storage policies in Supabase Dashboard > Storage > Policies

Google Sign-In Issues (Production)

  • Ensure APP_ENV=production in .env.local, and that ALLOWED_DOMAIN (if set) matches your team's email domain
  • Follow the full step-by-step in GOOGLE_AUTH_SETUP.md β€” it covers Supabase + Google Cloud config and the most common redirect_uri_mismatch fix

TypeScript Errors in IDE

If you see errors about process not being found, run:

npm install

These are dev-time warnings and won't affect runtime.


πŸ“„ License

Released under the MIT License β€” free to use, modify, and distribute. Just keep the copyright notice.

Owner: Arcady Media Inc.
Developer: Ritik


πŸ”— Links

About

AI-powered creative studio for generating on-brand ad creatives and visual assets with Google Gemini.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages