Codex: Screenshot to a Live Vite + React Landing Page
Hand Codex a screenshot or a brief and have it build a responsive Vite + React landing page, then deploy a Vercel preview and return the URL.
Run this workflow
CI-verified, 4/4 fixtures passing.
Build this with your agent
One copy-paste hands Claude Code, Codex, or Cursor the full recipe, steps included, nothing to fetch.
Intended Use
Turning a screenshot or a one-paragraph brief into a responsive landing page in a Vite + React repo, then a shareable Vercel preview, via Codex's @build-web-apps and @vercel plugins. CI verifies the deterministic build-readiness contract: the build is correctly wired (vite build) with its entry and deps present, the precondition for a green build the Codex docs require before shipping. The design interpretation, the full vite build, and the @vercel deploy are fenced (they need a model and your accounts).
Not for
- Pixel-perfect output, the model interprets the design, treat the preview as a draft
- Production deploys by default, preview is the default target; ask for production explicitly
- Anyone expecting CI to run the full Vite build or the deploy, those are fenced (model + accounts)
The Stack
Tested Against
codex@latestvite@6.xnode@20.xSide effects & data flow
- Network
- none, local only
- Writes
- ./package.json, ./index.html, ./src/, ./checkvite.mjs
- Credentials
- none required
Prerequisites
- Codex with the @build-web-apps and @vercel plugins
- A Vite + React repo
- A Vercel login for the preview deploy
Steps
- 1
Ask Codex to build it and ship a preview
Use @build-web-apps to turn the attached screenshot into a responsive landing page in this Vite + React repo. Match the layout and copy, keep it accessible. Then run the local build, and use @vercel to deploy a preview and give me the URL. Preview is the default target; production only if you ask.
- 2
What CI checks: the build is correctly wired (build-readiness)
The Codex docs require running the local build before handback, so a correctly wired build is the deterministic precondition. CI confirms the build script is vite build, vite and react are present, and the html entry points at a module source. No model, no account. (The full vite build that emits dist/ runs in your own CI or locally, npm ci then npm run build.)
mkdir -p src cat > package.json <<'EOF' { "name": "landing", "private": true, "scripts": { "dev": "vite", "build": "vite build", "preview": "vite preview" }, "dependencies": { "react": "^19.0.0", "react-dom": "^19.0.0" }, "devDependencies": { "vite": "^6.0.0", "@vitejs/plugin-react": "^4.3.0" } } EOF cat > index.html <<'EOF' <!doctype html> <html><head><meta charset="utf-8" /><title>Landing</title></head> <body><div id="root"></div><script type="module" src="/src/main.jsx"></script></body></html> EOF cat > src/main.jsx <<'EOF' import { createRoot } from 'react-dom/client' createRoot(document.getElementById('root')).render('Hello') EOF cat > checkvite.mjs <<'EOF' import { readFileSync, existsSync } from 'node:fs'; const pkg = JSON.parse(readFileSync('package.json', 'utf8')); const html = existsSync('index.html') ? readFileSync('index.html', 'utf8') : ''; const deps = { ...(pkg.dependencies||{}), ...(pkg.devDependencies||{}) }; let ok = true; function check(label, cond){ console.log(label + ': ' + (cond ? 'yes' : 'NO')); if(!cond) ok=false; } check('build script is vite build', String((pkg.scripts||{}).build||'').includes('vite build')); check('vite is a dependency', !!deps.vite); check('react is a dependency', !!deps.react); check('html entry references a module source', html.includes('type="module"') && html.includes('src/main')); check('source entry exists', existsSync('src/main.jsx')); if(!ok){ console.log('vite build-readiness check FAILED'); process.exit(1); } console.log('vite build-readiness check OK'); EOF node checkvite.mjs - 3
Let Codex build and deploy (the model + account step, not checked by CI)
Codex runs the full vite build and then @vercel deploys the preview and returns the URL. Both the design build (a model) and the deploy (your Codex + Vercel login) are non-deterministic and account-gated, so CI never runs them. The badge covers the build-readiness contract, not the live preview.
Eval, 4 fixtures
Last passed: verified todaybuild-wiredcontainstimeout 30s · max $0Expected:
build script is vite build: yesentry-okcontainstimeout 30s · max $0Expected:
html entry references a module source: yescheck-okcontainstimeout 30s · max $0Expected:
vite build-readiness check OKclean-exitexit_codetimeout 30s · max $0Expected:
0
Results
The fastest 'wow': a screenshot in a Slack thread becomes a shareable live page.
Did this work for you?
Our CI checks the setup runs. You tell us if the whole thing worked. Tell us straight.
Related workflows
- One AGENTS.md, no drift: prove CLAUDE.md is a real symlink and the generated files are in sync
- Self-host CodeWiki on private code: validate the config before you spend tokens
- Run GLM-5.2 for the bulk, escalate the hard turns to Opus 4.8
- codebase-memory-mcp: wire the knowledge graph, stop re-reading files
- OrcaRouter for coding: judge by passing tests, not by vibes
- Kilo Code: add an MCP tool and bind it to one mode
Liked this workflow?
Get new verified workflows in WebAfterAI, three issues a week (Tue, Thu, Sat).