Sign up for Continue, connect this sample Next.js app, and watch two performance checks catch real antipatterns on your PRs.
Two Continue checks that run as GitHub status checks on every PR:
-
Waterfall Detection (
.continue/checks/waterfall-detection.md): Catches async waterfalls based on Vercel's CRITICAL rules (1.1-1.5). Flags sequential awaits that could be parallelized, but correctly passes legitimately dependent operations. -
Bundle Size Guard (
.continue/checks/bundle-size-guard.md): Catches barrel imports, unnecessary'use client'directives, and missing dynamic imports for heavy libraries.
Both checks are already in this repo. You don't need to write them from scratch. The lab walks you through connecting the repo, opening test PRs, and watching the checks work.
A Next.js 15 App Router application with dashboard, products, and settings pages. The main branch is clean. The test branches introduce deliberate antipatterns.
├── app/
│ ├── layout.tsx
│ ├── page.tsx # Landing page (server component)
│ ├── dashboard/
│ │ ├── page.tsx # Dashboard (server component)
│ │ └── components/
│ │ ├── StatsPanel.tsx # Server component (no 'use client')
│ │ ├── ActivityFeed.tsx # Async server component
│ │ └── ChartSection.tsx # Client component, dynamic recharts
│ ├── api/
│ │ ├── users/route.ts # API route (clean)
│ │ └── analytics/route.ts # API route (clean)
│ ├── products/
│ │ ├── page.tsx # Product listing
│ │ └── [id]/page.tsx # Product detail
│ └── settings/
│ └── page.tsx # Settings page
├── components/
│ ├── ui/ # Shared UI components
│ ├── Header.tsx
│ └── Footer.tsx
├── lib/
│ ├── api.ts # API client functions
│ ├── auth.ts # Auth utilities
│ └── db.ts # Database queries
├── .continue/
│ └── checks/
│ ├── waterfall-detection.md # Check 1: Async waterfall detection
│ └── bundle-size-guard.md # Check 2: Bundle size enforcement
├── package.json
├── next.config.js
└── tsconfig.json
- GitHub account
- Node.js 18+
- Go to continue.dev and sign up for Mission Control
- Connect your GitHub account
- Fork this repo to your GitHub account
- In Mission Control, connect the forked repo
Checkpoint: You should see the repo in your Mission Control dashboard.
Open .continue/checks/ in your fork. Two checks are already defined:
waterfall-detection.mdcatches three patterns: deferred awaits (rule 1.1), independent sequential operations that should usePromise.all()(rule 1.2), and missing Suspense boundaries (rule 1.5). Critically, it knows to pass genuinely dependent sequential awaits.bundle-size-guard.mdcatches barrel imports from lucide-react, @mui/material, @radix-ui, lodash, date-fns, and react-icons. It flags unnecessary'use client'directives and static imports of heavy libraries that should usenext/dynamic.
These are plain markdown files in your repo. Version-controlled, reviewable, editable. This is what standards-as-code looks like.
- In your fork, open a PR from
test/waterfall-api-routetomain - Wait for checks to run (30-60 seconds)
- Expected: Waterfall Detection check flags the sequential awaits:
getUser,getPreferences, andgetNotificationsare awaited sequentially but all depend only onuserId. UsePromise.all().- Estimated savings: ~200-400ms per request
- Bundle Size Guard passes (no import or directive issues)
- Accept the waterfall suggestion
- Check goes green
What you're learning: The check identified three independent operations and suggested parallelizing them. It understood that userId was the only input each needed, and none depended on another's result.
- Open a PR from
test/barrel-imports-and-use-clienttomain - Wait for checks
- Expected:
- Bundle Size Guard flags barrel imports from
lucide-react(~200KB) and@radix-ui, suggests deep imports - Bundle Size Guard flags
'use client'on a component that only renders props, suggests removing it - Waterfall Detection passes (no async code in this PR)
- Bundle Size Guard flags barrel imports from
- Accept all suggestions
- Checks go green
What you're learning: Two different kinds of bundle size issues caught in one PR. The icon imports and the unnecessary client directive both add JavaScript to the bundle that doesn't need to be there.
This is the most important test.
- Open a PR from
test/legitimate-sequentialtomain - Wait for checks
- Expected: Waterfall Detection check passes:
- "Sequential awaits verified:
getPlandepends onuser.planIdfromgetUser.getInvoicesdepends onplan.billingIdfromgetPlan. No waterfall, operations are genuinely sequential."
- "Sequential awaits verified:
- No suggestions needed. Green check.
What you're learning: The check doesn't blindly flag every sequential await. It checks whether the operations actually depend on each other. This is why an AI check is better than a lint rule: it can reason about data flow.
- Open a PR from
test/clean-componenttomain - Wait for checks
- Expected: Both checks pass. Clean code. Green checks.
What you're learning: This is what most of your PRs look like once the checks are running. Verified. Passed. You move on.
Open .continue/checks/waterfall-detection.md in your fork and add a rule:
4. **Start promises early (rule 1.4):** In API routes and server
actions, flag patterns where a promise could be started at the
beginning of the function and awaited later, after other
synchronous work has been done. Suggest starting the promise
early and awaiting where the result is actually needed.Commit the change. This is now a more comprehensive waterfall check, and updating it took 30 seconds.
What you're learning: The check's rules are just markdown. Adding a rule is adding a paragraph. You control what's enforced and how strictly.
By the end of this lab you have:
- Two performance checks running on your repo (waterfall detection + bundle size)
- Verified they catch real violations (waterfall, barrel imports, unnecessary
'use client') - Verified they pass legitimate code (dependent sequential operations, clean components)
- Added a custom rule to expand coverage
You've seen the checks handle four scenarios correctly: catch a real waterfall, flag barrel imports and unnecessary directives, pass legitimately sequential code, and verify clean components.
Next step: Add .continue/checks/ to your production Next.js repo. Start with the CRITICAL rules and expand from there.