Rams MCP · The full engine, now in your coding agent
vercel on GitHub

vercel/turbo

Reviewed against Rams quality heuristics: accessibility, color, typography, spacing, components, motion, UX, and craft.

30 files reviewed·July 25, 2026

View on GitHub

Low

Design risk in this codebase.

7issues
Serious & Moderate · top 5 shown below

Top fix

Add a retry path to the error state instead of a dead end

See the fix

Verdict

Solid bones, unfinished interior: security and hierarchy fundamentals are right, but every stateful moment (loading, error, retry) is missing. The biggest risk is a dead-end error state with no recovery, paired with scaffold copy that never became real content.

Files Rams reviewed

examples/with-docker/apps/web/src/app/page.tsx

apps/docs/app/[lang]/(home)/components/templates.tsx

apps/docs/app/[lang]/(extra)/[...slug]/page.tsx

apps/docs/app/[lang]/(home)/blog/[...slug]/page.tsx

apps/docs/app/[lang]/(home)/blog/page.tsx

apps/docs/app/[lang]/(home)/page.tsx

apps/docs/app/[lang]/(home)/showcase/page.tsx

apps/docs/app/[lang]/(openapi)/docs/openapi/[[...slug]]/page.tsx

apps/docs/app/[lang]/docs/[[...slug]]/page.tsx

apps/docs/app/[lang]/layout.tsx

examples/basic/apps/docs/app/page.tsx

examples/basic/apps/web/app/page.tsx

examples/kitchen-sink/apps/storefront/src/app/layout.tsx

examples/kitchen-sink/apps/storefront/src/app/page.tsx

examples/non-monorepo/app/page.tsx

examples/with-biome/apps/docs/app/page.tsx

examples/with-biome/apps/web/app/page.tsx

examples/with-changesets/apps/docs/src/app/layout.tsx

examples/with-changesets/apps/docs/src/app/page.tsx

examples/with-docker/apps/web/src/app/layout.tsx

examples/with-microfrontends/apps/docs/app/nested/page.tsx

examples/with-microfrontends/apps/docs/app/page.tsx

examples/with-microfrontends/apps/web/app/page.tsx

examples/with-nestjs/apps/web/app/page.tsx

examples/with-nextjs-elysia/apps/web/src/app/layout.tsx

examples/with-nextjs-elysia/apps/web/src/app/page.tsx

examples/with-npm/apps/docs/app/page.tsx

examples/with-npm/apps/web/app/page.tsx

examples/with-otel/apps/docs/app/page.tsx

examples/with-otel/apps/web/app/page.tsx

96/100

UX

2 serious
UXSerious

examples/with-docker/apps/web/src/app/page.tsx:47

Error state is a dead end with no retry path

After "Unable to fetch response" renders, the only other control on the page is the name `<input>` and the same "Submit" button, but there's no explicit retry affordance tied to the error block itself. The user has to rediscover the form is still usable.

Why it matters

Users who hit a failed request are left staring at an error with no clear next step, increasing abandonment instead of recovery.

Fix

Pair every error state with a visible retry action that re-triggers the failed request.

{error && (
  <div>
    <h3>Error</h3>
    <p>{error}</p>
  </div>
)}
{error && (
  <div role="alert">
    <h3>Error</h3>
    <p>{error}</p>
    <Button onClick={onSubmit}>Retry</Button>
  </div>
)}
UXSerious

examples/with-docker/apps/web/src/app/page.tsx:50

Submit button gives no feedback while the request is in flight

The `onSubmit` handler awaits `fetch(...)` and `result.json()` but the "Submit" button stays enabled and unchanged the entire time. Nothing in the JSX reflects a pending state.

Why it matters

Without a loading or disabled state, users can click Submit multiple times during a slow request, firing duplicate calls with no indication anything is happening.

Fix

Track a pending/loading state and disable the trigger button until the request resolves.

<Button type="submit">Submit</Button>
<Button type="submit" disabled={isSubmitting}>{isSubmitting ? "Submitting…" : "Submit"}</Button>
98/100

Typography

1 serious
TypographySerious

examples/basic/apps/docs/app/page.tsx:95

Text arrow glyph in footer link breaks icon consistency

The footer link "Go to turborepo.dev →" uses a raw "→" character next to an `<Image src="/globe.svg">` icon. The glyph renders at whatever weight and baseline the surrounding font gives it, while the adjacent SVG icon has its own fixed stroke weight.

Why it matters

A text glyph next to a vector icon renders at inconsistent weight and alignment across fonts and platforms, making the footer row look unfinished next to "Examples" which uses a clean icon+label pattern.

Fix

Use an inline SVG arrow icon at a matched stroke weight instead of a text glyph for directional affordances.

Go to turborepo.dev →
Go to turborepo.dev <ArrowRightIcon aria-hidden width={12} height={12} />

Get this score on every PR.

Rams reviews each pull request on your repo and posts inline one-click fixes — about a minute per review.

Install Rams free
98/100

Components

1 serious
ComponentsSerious

examples/basic/apps/docs/app/page.tsx:66

Button override bypasses shared component's own styling API

`<Button appName="docs" className={styles.secondary}>Open alert</Button>` forces the shared Button into secondary styling via a raw className instead of a variant prop, while the two `<a>` CTAs above it use `styles.primary` / `styles.secondary` directly.

Why it matters

Styling a shared component through className overrides instead of its intended prop API means the next place Button gets used can silently diverge in appearance, and Button's internal styles can conflict with the injected class.

Fix

Style shared components through their exposed variant/prop API, not by injecting external classNames.

<Button appName="docs" className={styles.secondary}>
  Open alert
</Button>
<Button appName="docs" variant="secondary">
  Open alert
</Button>
98/100

Craft

1 serious
CraftSerious

examples/basic/apps/web/app/page.tsx:26

Page body is unedited scaffold copy, not real product content

The only body content on the page is the ordered list "Get started by editing `apps/web/app/page.tsx`" and "Save and see your changes instantly.", followed by the default Vercel "Deploy now" / "Read our docs" CTAs.

Why it matters

Shipping the Next.js scaffold text as the page's actual content signals the page was never built out, and any real user landing here gets developer instructions instead of a product experience.

Fix

Replace scaffold placeholder copy with real page content before shipping.

<li>
  Get started by editing <code>apps/web/app/page.tsx</code>
</li>
<li>Save and see your changes instantly.</li>
<li>Real onboarding copy for this product</li>
<li>Actual next step for the user, not the developer</li>

Accessibility

No issues found

Color

No issues found

Spacing

No issues found

Motion

No issues found

Working well

  • The "Deploy now" and "Read our docs" CTAs are correctly differentiated: "Deploy now" uses `styles.primary` as a filled action with the Vercel logomark, while "Read our docs" uses `styles.secondary` as a lighter-weight link. That's the right pattern, one clear entry point with a supporting secondary action.
  • The Name input is correctly tied to its label via `htmlFor="name"` / `id="name"`, so the field announces properly to assistive tech instead of relying on placeholder text alone.

Scored July 25, 2026 with Rams Engine v0.0.3 · Engine changelog
First scored May 13, 2026: 77/100. This rescore on v0.0.3: 89/100.

This page is an automated design review of vercel/turbo’s UI code: 30 files read against 308 versioned rules covering accessibility, color, typography, spacing, components, UX, motion, and craft. The score is out of 100; confirmed criticals cap it — one at 59, two at 49, three or more at 39.

More design scores

Score your own repo.

Free on public repos, no account. The same engine that scored this page reads your UI code and mints a score page like this one.

Public repos only. The full engine reviews the UI code and mints a public score page — we email you the link too. Already-scored repos open instantly.

Or get a design review on every pull requestInstall Rams