A clean, minimal Next.js starter template with modern tooling and semantic component architecture. Built for developers who want a solid foundation without framework lock-in.
- Next.js 15 - React framework with App Router
- TypeScript - Full type safety and developer experience
- SCSS - Enhanced CSS with variables, nesting, and functions
- CSS Modules - Component-scoped styling
- MDX - Markdown with React components
- Turbopack - Fast development builds (10x faster than Webpack)
- Biome - Lightning-fast linting and formatting
- GitHub Flavored Markdown - Tables, task lists, strikethrough, autolinks
- React Components in MDX - Mix interactive components with content
- Flexible Content Structure - Add
.mdxfiles anywhere in your app
- Pure SCSS + CSS Modules - No utility classes, semantic component styling
- CSS Custom Properties - Clean theming system with dark mode support
- Responsive Design - Mobile-first approach with clean breakpoints
- Font Optimization - Automatic font loading with
next/font
- Pre-commit Hooks - Automatic TypeScript checking before commits
- Hot Module Replacement - Instant updates during development
- Import Aliases - Clean imports with
@/prefix
# Clone or use this template
git clone <repository-url>
cd simple-nextjs-starter
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Open http://localhost:3000You'll see: A clean welcome page with SCSS Modules styling - ready for your content and components!
src/
βββ app/ # Next.js App Router
β βββ globals.css # Global styles & CSS custom properties
β βββ layout.tsx # Root layout with font optimization
β βββ page.tsx # Home page (uses CSS Modules)
β βββ page.module.scss # Component styles with SCSS features
βββ lib/
β βββ utils.ts # Utility functions (class merging, etc.)
βββ styles/
βββ layout.css # Global reset & layout utilities
βββ typography.css # Base typography system
# Development
pnpm dev # Start dev server with Turbopack
pnpm build # Production build
pnpm start # Start production server
# Code Quality
pnpm lint # Check code with Biome
pnpm format # Format code with Biome
pnpm type:check # TypeScript validation
# Git Hooks
pre-commit install # Set up pre-commit hooks
pre-commit run --all-files # Run hooks manually# Create a new MDX page
mkdir src/app/blog
touch src/app/blog/page.mdx# My Blog Post
This is **GitHub Flavored Markdown** with semantic React components!
## Task Progress
- [x] Set up Next.js with MDX
- [x] Configure SCSS and CSS Modules
- [ ] Write amazing content
- [ ] Deploy to production
## Interactive Elements
<Button variant="primary">Get Started</Button>
<Alert type="info">This is semantic, just like HTML elements!</Alert>
## Code Example
Here's how to use our components:
```tsx
<Card>
<CardHeader>
<CardTitle>Welcome</CardTitle>
</CardHeader>
<CardContent>
<p>Clean, semantic components make content readable.</p>
</CardContent>
</Card>
```The beauty is in the semantic simplicity - components work like enhanced HTML elements.
### Component with SCSS Modules
```scss
// Component.module.scss
.container {
padding: 1rem;
background: var(--color-background);
&.variant {
border: 1px solid var(--color-primary);
}
.title {
font-size: 1.5rem;
color: var(--color-foreground);
}
}
// Component.tsx
import styles from "./Component.module.scss";
import { cn } from "@/lib/utils";
export function Component({ variant = false }) {
return (
<div className={cn(styles.container, variant && styles.variant)}>
<h2 className={styles.title}>Hello World</h2>
</div>
);
}Create reusable components that work like enhanced HTML:
// src/components/Button.tsx
import styles from "./Button.module.scss";
interface ButtonProps {
variant?: "primary" | "secondary";
children: React.ReactNode;
onClick?: () => void;
}
export function Button({
variant = "primary",
children,
...props
}: ButtonProps) {
return (
<button className={styles[variant]} {...props}>
{children}
</button>
);
}// src/components/Alert.tsx
import styles from "./Alert.module.scss";
interface AlertProps {
type?: "info" | "warning" | "error";
children: React.ReactNode;
}
export function Alert({ type = "info", children }: AlertProps) {
return (
<div className={styles[type]} role="alert">
{children}
</div>
);
}Then use them in MDX like semantic HTML:
<Button variant="primary">Clean & Simple</Button>
<Alert type="info">Just like HTML elements!</Alert>This starter embraces semantic, component-based design - just like semantic HTML, but enhanced:
- Semantic Components -
<Button>,<Alert>,<Card>work like HTML elements - No Inline Logic - Components are defined separately, used cleanly in content
- CSS Modules - Component-scoped styles with SCSS features
- CSS Custom Properties - Consistent theming and design tokens
- No Framework Lock-in - Pure CSS and semantic React you own and control
<!-- Clean, readable, semantic -->
<Alert type="info">Important information for users</Alert>
<Button variant="primary">Get Started</Button>
<!-- NOT this: -->
<!-- export function Button() { ... } -->
<!-- <button onClick={handleClick}>Complex inline logic</button> -->Think enhanced HTML - components should feel as natural as <p>, <h1>, <img> tags.
- Components are defined once, used everywhere semantically
- Content files (
.mdx) focus purely on content and structure - Component logic lives in dedicated component files
- Styling is scoped to components via CSS Modules
- Components work like enhanced HTML elements
- Clean, declarative API:
<Button variant="primary">not<div className="btn-primary"> - Self-documenting through TypeScript interfaces
- Composable and predictable behavior
β
GOOD: Separation of concerns
βββ src/components/Button.tsx # Component definition & logic
βββ src/components/Button.module.scss # Component-specific styles
βββ src/app/blog/page.mdx # Clean content usage: <Button>
β AVOID: Mixed concerns
βββ src/app/blog/page.mdx # export function Button() { ... }
# <Button onClick={complexLogic}>
This approach ensures:
- Reusability - Define once, use anywhere
- Maintainability - Change component logic in one place
- Readability - Content files stay focused on content
- Type Safety - Full TypeScript support across the boundary
- Strict mode enabled
- Path aliases configured (
@/forsrc/) - MDX type definitions included
- Replaces ESLint + Prettier for better performance
- Configured for Next.js and React best practices
- Automatic import organization
- GitHub Flavored Markdown enabled
- Custom components supported
- Optimized for static generation
- Content-Rich Sites - Blogs, documentation, marketing pages
- Component Libraries - Build reusable components with clean styles
- Rapid Prototyping - Start fast without configuration overhead
- Teams - Consistent tooling and clear patterns
- Next.js Documentation - Framework features and API
- MDX Documentation - Markdown + React components
- SCSS Guide - Enhanced CSS features
- CSS Modules - Component-scoped styling
Deploy easily on Vercel:
Or any static hosting provider:
pnpm build # Creates ./out directory
# Upload ./out to your hosting providerReady to build something amazing! π