All skills
mblode avatar

/ui-design

@e7db33d
by Matthew Blodemblode/agent-skills136 stars
12

Designs and builds React/Next/Tailwind UI and audits visual and interaction defects. Use when asked to "build a landing page", "extract our design system", "add dark mode", "make this responsive", "remove UI slop", or "audit this component". For product decisions use product-design; for browser measurements use ui-verification; for motion use ui-animation.

Use this Skill: https://skilld.dev/gh/mblode/agent-skills/ui-design

This session only. Nothing lands on disk.

rulesasync-no-suspense-boundary.md

≈921 tokens on demand. Your agent reads this file only when SKILL.md points to it.

Async server component without Suspense boundary

In the App Router and React 19, an async server component with no enclosing <Suspense> boundary blocks the whole route from streaming. Users wait for the slowest fetch before seeing anything: no shell, no skeleton, no progressive paint. Wrap the slow async tree in <Suspense fallback={...}> to unblock the rest of the page.

What goes wrong

Page renders four widgets; one calls a slow third-party API. With no Suspense boundary, the whole route hangs on that fetch. TTFB explodes, the user sees a blank screen, and nothing paints until the slowest dependency resolves.

Detection

Surfaces: dashboard, list, search, loading-state, checkout, onboarding (anywhere server-fetched data renders).

Static signals:

  1. Find async server components: rg '^export (default )?async function' --type=ts app/ src/app/.
  2. For each, walk up the tree to check whether the parent renders it inside <Suspense>.
  3. Confirm the route segment lacks a loading.tsx (Next.js auto-wraps the segment in Suspense when present).
  4. Flag if neither a <Suspense> ancestor nor a sibling loading.tsx exists.

Concrete commands:

# Async server components in the App Router
rg '^export (default )?async function' --type=ts app/ src/app/ -l

# Files that import Suspense
rg "from 'react'" --type=ts -l | while read f; do
  rg -l 'Suspense' "$f"
done

# Routes missing loading.tsx
find app src/app -type f -name 'page.tsx' 2>/dev/null | while read p; do
  dir=$(dirname "$p")
  [ ! -f "$dir/loading.tsx" ] && echo "$dir: no loading.tsx"
done

False-positive guards:

  • Skip if a loading.tsx exists at any ancestor segment; Next.js wraps the segment in Suspense automatically.
  • Skip if the component is a leaf and renders inline static markup (no awaits).
  • Skip files annotated // ui-audit-ignore:async-no-suspense-boundary.

Fix

Wrap the slow async tree in <Suspense> with a skeleton fallback that matches the loaded layout (CLS-safe).

// before: entire dashboard waits for SlowWidget
export default async function DashboardPage() {
  return (
    <main>
      <FastWidget />
      <SlowWidget /> {/* awaits a 3s API */}
      <AnotherWidget />
    </main>
  );
}

// after: SlowWidget streams in; rest of the page paints immediately
import { Suspense } from 'react';

export default function DashboardPage() {
  return (
    <main>
      <FastWidget />
      <Suspense fallback={<SlowWidgetSkeleton />}>
        <SlowWidget />
      </Suspense>
      <AnotherWidget />
    </main>
  );
}

Docs:

Default tier and overrides

Defaults to: fix-this-sprint

Surface overrides:

Surface Tier
Dashboard with >2 widgets release-blocker
Checkout / Sign-in release-blocker (TTFB on critical path)
Marketing landing fix-this-sprint
Internal admin backlog

Defer-to (when this is another tool's job)

  • Lighthouse for measured TTFB / LCP regressions.
  • Vercel Speed Insights for field measurement of streaming impact.
  • ESLint plugin eslint-plugin-react-server-components for write-time checks.

Suppression

{/* ui-audit-ignore:async-no-suspense-boundary, leaf is sync, no await */}
<StaticWidget />

Source: SKILL.md on GitHub

No alerts8d5 checks · Risk SAFE
  • Gen Agent Trust Hub8d

    A comprehensive UI design and auditing skill that uses standard developer tools and trusted services like Tailwind CSS and placeholder asset APIs to build and verify React/Next.js interfaces. It includes explicit guardrails to prevent instruction following from analyzed project files.

  • Socket8d

    No alerts

  • Snyk8d

    Risk: LOW · No issues

  • Runlayer6mo

    4/5 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e7db33d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 3 hours ago.

Activeupdated last week

README badge

README badge for mblode/agent-skills/ui-design