modelscope.cn

nextjs-fullstack

Next.js fullstack development guidelines for React 19 and Next.js 15+.

Installation

$ npx skills add https://modelscope.cn

Summary

  • Next.js fullstack development guidelines for React 19 and Next.js 15+.
  • Use when building Next.js applications with Feature-Sliced Design, TailwindCSS v4, ShadCN, Jotai, React Query, and Supabase integration.
  • Covers file naming, component architecture, testing with Vitest/Playwright, UI/UX design patterns, and Toss frontend principles.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from modelscope.cn · top by installs.

npx skills add https://modelscope.cn

Browse all from modelscope.cn

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,543 B

History

  1. First recorded snapshot · 0 installs

SKILL.md

Next.js Fullstack Development

Quick Reference

  • Next.js Convention: See [nextjs-convention.md](references/nextjs-convention.md) for FSD structure and package conventions
  • UI/UX Design: See [design-rules.md](references/design-rules.md) for design patterns and accessibility
  • Playwright Testing: See [playwright-test-guide.md](references/playwright-test-guide.md) for E2E tests
  • Toss Principles: See [toss-frontend.md](references/toss-frontend.md) for readability, predictability, cohesion

Core Conventions

Package Manager

Use pnpm instead of npm, bunx instead of npx.

File Naming

  • All files: kebab-case (e.g., user-profile.tsx, auth-form.tsx)
  • Components: PascalCase for component names, kebab-case for files
  • Functions/Variables: camelCase

Directory Structure (Feature-Sliced Design)

├── app/                     # Next.js App Router (routing only)
│   ├── (routes)/example/page.tsx  # Re-export from FSD pages
│   └── api/                 # API Route Handlers
└── src/
    ├── pages/               # FSD Pages Layer
    ├── widgets/             # Header, Sidebar, Footer
    ├── features/            # User scenarios (auth, checkout)
    ├── entities/            # Business entities (user, product)
    └── shared/              # Shared resources
        ├── ui/              # ShadCN components
        ├── lib/             # Utilities
        └── api/             # Supabase clients

Layer Import Rules

Upper layers can only import from lower layers: apppageswidgetsfeaturesentitiesshared

// Import through public API only
import { UserCard } from '@/entities/user';     // Correct
import { UserCard } from '@/entities/user/ui/user-card'; // Wrong

Tech Stack

Category Technology
UI Components ShadCN (pnpm dlx shadcn@latest add [name])
Icons lucide-react
State Management Jotai
Data Fetching React Query
Styling TailwindCSS v4 (globals.css only)
Testing Vitest + Playwright
Database Supabase

React 19 / Next.js 15 Patterns

Server vs Client Components

// Default: Server Component (no directive needed)
export function ServerPage() {
  return <div>Server rendered</div>;
}

// Client Component: explicit directive
'use client';
export function InteractiveButton() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(c => c + 1)}>{count}</button>;
}

Async APIs

const cookieStore = await cookies();
const headersList = await headers();
const params = await props.params;
const searchParams = await props.searchParams;

Server Actions

// src/features/auth/api/actions.ts
'use server';

export async function signIn(formData: FormData) {
  // Server action logic
}

Code Quality Principles

Naming Magic Numbers

const ANIMATION_DELAY_MS = 300;
await delay(ANIMATION_DELAY_MS);

Separate Conditional Components

function SubmitButton() {
  const isViewer = useRole() === 'viewer';
  return isViewer ? <ViewerSubmitButton /> : <AdminSubmitButton />;
}

Consistent Return Types

type ValidationResult = { ok: true } | { ok: false; reason: string };

function checkIsNameValid(name: string): ValidationResult {
  if (name.length === 0) return { ok: false, reason: 'Name cannot be empty.' };
  return { ok: true };
}

Testing

Vitest Setup

// vitest.config.mts
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({
  plugins: [tsconfigPaths(), react()],
  test: { environment: 'jsdom' },
});

Playwright Locator Priority

// 1. Role and accessibility (preferred)
page.getByRole('button', { name: 'Login' });
page.getByLabel('Email');

// 2. Text
page.getByText('Create account');

// 3. Test ID (last resort)
page.getByTestId('submit-button');