Submit your code. Get roasted (or reviewed). Survive the feedback.
DevRoast is a web app that lets developers paste code snippets and receive AI-powered analysis. Choose between a constructive technical review or "roast mode" — a sarcastic, humorous (but technically accurate) teardown of your code.
- Code submission — paste any code snippet with auto-detected or manually selected language
- Two analysis modes — constructive review or sarcastic roast mode
- Structured results — quality score (1–10), verdict, issues by severity, and an improved version of your code
- Leaderboard — public ranking of the most interesting (or disastrous) submissions
- Rate limiting — abuse prevention per IP
| Layer | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| UI | React 19, Tailwind CSS v4 |
| Variant system | tailwind-variants + tailwind-merge |
| API | tRPC v11 |
| Database ORM | Drizzle ORM |
| Database | PostgreSQL |
| AI | OpenAI API |
| Syntax highlighting | Shiki + highlight.js |
| Forms | React Hook Form + Zod |
| Fonts | JetBrains Mono, IBM Plex Mono |
┌─────────────┐ ┌─────────────┐ ┌──────────────┐
│ CodeForm │───▶│ tRPC Router │───▶│ submissions │
│ (Client) │ │ submissions │ │ table │
└─────────────┘ └──────┬──────┘ └──────┬───────┘
│ │
▼ ▼
┌─────────────┐ ┌──────────────┐
│ OpenAI API │ │ roast_results│
│ (roast.ts) │ │ table │
└─────────────┘ └──────────────┘
src/
├── app/ # Next.js App Router — pages and layouts (SSR by default)
├── components/ # React components (UI primitives + feature components)
├── server/ # tRPC server — context, procedures, and routers
├── db/ # Drizzle ORM — schema, enums, migrations, and seed
└── lib/ # Utilities — tRPC client/server helpers, rate limiting, AI
src/app/ — All pages are Server Components. Routes:
/— home with the code submission form/roast/[id]— result page for a single submission/leaderboard— public ranking of submissions
src/components/ — Named-export React components. UI primitives live under ui/. Feature components (form, result display, metrics, skeletons) live at the root of components/.
src/server/ — tRPC setup. One router per entity (submissions, leaderboard), aggregated into AppRouter. Context is typed and passed through all procedures.
src/db/ — Drizzle schema split into individual table files. Enums (language, submission_status, verdict) live separately. A seed script populates development data.
src/lib/ — tRPC client for Client Components, tRPC caller for Server Components, rate limiting utility, and the AI roast generation module.
| Field | Type | Description |
|---|---|---|
id |
uuid | Primary key |
code |
text | The submitted source code |
language |
enum | Language selected or auto-detected |
status |
enum | pending → processing → completed / failed |
ipHash |
text | Hashed IP for rate limiting |
createdAt |
timestamp | Submission time |
completedAt |
timestamp | When AI processing finished |
| Field | Type | Description |
|---|---|---|
score |
integer (1–10) | Overall code quality score |
verdict |
enum | clean / acceptable / messy / disaster / catastrophe |
roastTitle |
text | Catchy title for the analysis |
analysis |
text | Full AI-generated review |
roastQuotes |
string[] | Memorable one-liners |
issues |
array | Issues with severity, line, message, and suggestion |
metrics |
object | Lines of code, complexity, maintainability |
- Node.js 20+
- PostgreSQL (or Docker)
- OpenAI API key
npm installCreate a .env file at the root:
DATABASE_URL=postgresql://user:password@localhost:5432/devroast
LLM_PROVIDER=openai
LLM_API_KEY=<your-openai-api-key>
LLM_MODEL=gpt-4-turbo# Generate and apply migrations
npm run db:push
# (Optional) Seed with sample data
npm run db:seednpm run devOpen http://localhost:3000.
| Command | Description |
|---|---|
npm run dev |
Start Next.js in development mode |
npm run build |
Build for production |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run format |
Format code with Prettier |
npm run db:generate |
Generate Drizzle migration files |
npm run db:push |
Apply schema to the database |
npm run db:studio |
Open Drizzle Studio (DB GUI) |
npm run db:seed |
Seed the database with sample data |
Submissions are processed by the generateRoast function in src/lib/ai/. It builds a prompt based on the selected mode and calls the configured LLM provider (OpenAI by default), then parses the structured response into score, verdict, issues, and a suggested improved version of the code.
Normal mode — technical analysis with constructive, professional feedback.
Roast mode — same technical accuracy, but delivered with sarcasm and memorable commentary.
Each IP is limited to 10 submissions per hour. The limit is enforced server-side using the hashed IP stored on each submission record — no external service required.
- Named exports only — no default exports
tv()from tailwind-variants for component variantscn()(tailwind-merge + clsx) for className composition- Dark theme only — all design tokens defined in
globals.css - Components accept a
classNameprop for external overrides