A production-grade AI video script generator with a cinematic editorial interface. Paste an idea, choose a tone and length, and generate three polished script options with hooks, sections, B-roll notes, pauses, CTAs, and viral score metadata.
- Framework: Next.js App Router, React, TypeScript
- Styling: Tailwind CSS v4 with custom editorial design tokens
- Animation/UI: Framer Motion, Lucide React, next-themes
- AI Provider: OpenRouter Chat Completions API
- Default Model:
anthropic/claude-sonnet-4 - Testing: Vitest unit tests and Playwright e2e tests
- Deployment: Vercel
# 1. Install dependencies
npm install
# 2. Create local env file
cp .env.example .env.local
# 3. Add your OpenRouter key
# OPENROUTER_API_KEY=sk-or-v1-...
# 4. Run locally
npm run devOpen http://localhost:3000.
| Variable | Required | Description |
|---|---|---|
OPENROUTER_API_KEY |
Yes | Server-side OpenRouter API key. Never expose this in client code. |
OPENROUTER_MODEL |
No | Model used by /api/generate. Defaults to anthropic/claude-sonnet-4. |
OPENROUTER_MAX_TOKENS |
No | Optional completion-token cap for low-credit OpenRouter accounts. The API also retries with a smaller cap when OpenRouter reports an affordable budget. |
NEXT_PUBLIC_SITE_URL |
No | Sent as OpenRouter HTTP-Referer. Defaults locally to http://localhost:3000. |
Example:
OPENROUTER_API_KEY=
OPENROUTER_MODEL=anthropic/claude-sonnet-4
OPENROUTER_MAX_TOKENS=
NEXT_PUBLIC_SITE_URL=http://localhost:3000| Command | What it does |
|---|---|
npm run dev |
Start the Next.js development server |
npm run build |
Create a production build |
npm start |
Start the production server after building |
npm run lint |
Run ESLint |
npm test |
Run Vitest unit tests |
npm run test:e2e |
Run Playwright e2e tests |
npm run test:all |
Run unit and e2e tests |
npm run verify |
Run lint, build, unit tests, and e2e tests |
scriptforge/
├── app/
│ ├── api/generate/route.ts # Server-only OpenRouter endpoint wrapper
│ ├── globals.css # Global styles and Tailwind theme tokens
│ ├── layout.tsx # Root metadata/layout
│ ├── page.tsx # Main script-generation UI
│ └── providers.tsx # App-level providers
├── lib/
│ ├── constants.ts # Tone and length options
│ ├── prompts.ts # Prompt builders for multi-script output
│ └── types.ts # Shared TypeScript types
├── public/ # Static assets
├── tests/
│ ├── e2e/ # Playwright tests
│ └── unit/ # Vitest tests
├── .env.example # Safe env template
├── eslint.config.mjs # ESLint config
├── playwright.config.ts # Playwright config
├── vitest.config.ts # Vitest config
└── package.json
- The browser sends
{ prompt, tone, length }toPOST /api/generate. - The route validates the request body and rejects invalid prompt, tone, or length values.
lib/prompts.tsbuilds a tone-aware system prompt and a topic-specific user message.- The server calls OpenRouter's OpenAI-compatible
/chat/completionsendpoint withanthropic/claude-sonnet-4by default. - The model is asked to produce JSON beginning with
{"scripts":[. - The route extracts and validates the JSON, clamps viral scores, and returns up to three script options.
The API key stays server-side in .env.local. The browser never receives the key or raw OpenRouter response.
ScriptForge uses a warm editorial style inspired by premium writing tools:
- Parchment/light and dark workspace themes
- Serif display typography for editorial tone
- Warm neutral surfaces and borders
- Red, blue, and green accents for tone-specific script options
- Animated prompt placeholder, theme transitions, and script result cards
The repository intentionally tracks only source, tests, public assets, and safe configuration. The following are ignored and should not be pushed:
.env.localand all real env filesnode_modules/,.next/, build output, coverage, and test artifacts- Playwright reports and screenshots
- Local AI-agent/tooling folders such as
.claude/,.claude-flow/,.agents/, andagents/ - Generated design/code-analysis artifacts such as
design/,design-images/,graphify-out/, andDESIGN.md - Ad-hoc local scripts such as
test-llm.js, especially because they can contain secrets
If a secret is ever committed or shared publicly, rotate it immediately in OpenRouter.
- Push the cleaned repository to GitHub.
- Import the project in Vercel.
- Add
OPENROUTER_API_KEYin Vercel Project Settings. - Optionally add
OPENROUTER_MODEL=anthropic/claude-sonnet-4. - Deploy.
.env.exampleis safe to commit and documents required variables..env.localis ignored and should contain your real OpenRouter key.- The default model was verified through OpenRouter without starting the dev server.