Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ node_modules

# next.js
.next
out

# vercel
.vercel
Expand All @@ -13,10 +14,12 @@ node_modules

# debug
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env.local
.env.development.local
.env.test.local
Expand All @@ -25,3 +28,23 @@ yarn-error.log*
# docker file
Dockerfile
docker-compose.yml

# git
.git
.gitignore

# ci/cd
.github

# editor
.vscode
.idea

# testing
coverage

# misc
*.log
README.md
CLAUDE.md
LICENSE
16 changes: 0 additions & 16 deletions .eslintrc.json

This file was deleted.

56 changes: 32 additions & 24 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,60 +1,68 @@
# This is a basic workflow to help you get started with Actions

name: CI to Docker Hub

# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ main ]
branches: [main]
pull_request:
branches: [ main ]

# Allows you to run this workflow manually from the Actions tab
branches: [main]
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Check Out Repo
uses: actions/[email protected]
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Enable Corepack
run: corepack enable

- name: Install pnpm
run: corepack prepare pnpm@latest --activate

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Run Biome check
run: pnpm check

- name: Type check
run: pnpm type-check

- name: Build Next.js
run: pnpm build

# Set up cache for the builder
- name: Cache Docker layers
uses: actions/cache@v2.1.4
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-

# Login to docker
- name: Docker Login
uses: docker/[email protected]
- name: Docker Login
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}

# Set up docker buildx
- name: Docker Setup Buildx
uses: docker/setup-buildx-action@v1.1.1
uses: docker/setup-buildx-action@v3

# Build and push docker images
- name: Build and push Docker images
uses: docker/build-push-action@v2.3.0
uses: docker/build-push-action@v5
with:
context: ./
file: ./Dockerfile
builder: ${{ steps.buildx.outputs.name }}
push: true
tags: danangekal/next-typescript-starter:latest
tags: danangekal/next-typescript-starter:latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache

Expand Down
9 changes: 8 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,12 @@

# debug
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local
.env.local
.env.development.local
.env.test.local
Expand All @@ -33,5 +35,10 @@ yarn-error.log*
# vercel
.vercel

# package lock
# typescript
*.tsbuildinfo
next-env.d.ts

# package locks (pnpm only)
package-lock.json
yarn.lock
3 changes: 1 addition & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
pnpm lint-staged
4 changes: 0 additions & 4 deletions .husky/prepare-commit-msg

This file was deleted.

6 changes: 2 additions & 4 deletions .lintstagedrc.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
{
"*.{css,scss,json,md,html}": ["prettier --ignore-path .gitignore --write"],
"*.{js,ts,tsx}": [
"prettier --ignore-path .gitignore --write",
"eslint --ignore-path .gitignore --quiet --fix"
"*": [
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true"
]
}
11 changes: 0 additions & 11 deletions .prettierrc.json

This file was deleted.

136 changes: 136 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

Next.js 15 TypeScript starter template with modern tooling, Docker support, and pre-configured code quality tools.

**Tech Stack:**
- Next.js 15.5.4 (Pages Router) with Turbopack
- React 19.2.0
- TypeScript 5.7.3
- pnpm package manager
- Biome (replaces ESLint + Prettier)

**Requirements:**
- Node.js >= 22.0.0
- pnpm >= 9.0.0 (via Corepack or global install)
- Package manager locked to [email protected] via `packageManager` field

## Development Commands

```bash
# Install dependencies
pnpm install

# Development server with Turbopack (http://localhost:3000)
pnpm dev # Uses --turbopack flag automatically

# Production
pnpm build # Build for production
pnpm start # Start production server

# Code Quality
pnpm lint # Run Biome linter
pnpm format # Format code with Biome
pnpm check # Run Biome check and auto-fix (recommended)
pnpm type-check # TypeScript type checking
pnpm type-check:watch # TypeScript type checking in watch mode

# Testing
pnpm test # Placeholder (no test framework configured)

# Docker
docker build -t next-typescript-starter .
docker run --rm -it -p 3000:3000 next-typescript-starter
docker-compose up
```

## Project Architecture

**Next.js Pages Router Structure:**
- `pages/` - File-based routing (Pages Router, not App Router)
- `pages/_app.tsx` - Custom App component, imports global styles
- `pages/_document.tsx` - Custom Document for HTML structure
- `pages/index.tsx` - Home page
- `pages/api/` - API routes (serverless functions)
- `components/` - Reusable React components
- `styles/` - CSS files (globals.css, CSS Modules)
- `public/` - Static assets

**Path Aliases:**
- `@/*` resolves to project root (configured in tsconfig.json)
- Example: `import '@/styles/globals.css'`

## Code Quality Tools

### Biome (Linter + Formatter)

**Configuration**: `biome.json`

Biome replaces both ESLint and Prettier for better performance and consistency.

**Linting Rules:**
- `noConsole: error` - Console statements not allowed in production code
- `noUnusedVariables: error` - Unused variables not allowed
- `noUnusedImports: error` - Unused imports not allowed
- `useImportType: error` - Enforce type-only imports when applicable
- Auto-organizes imports

**Formatting Style:**
- Single quotes for JS/TS
- Double quotes for JSX
- 2-space indentation
- 80 character line width
- Trailing commas everywhere
- Semicolons always
- Arrow function parentheses always

**Usage:**
- Run `pnpm check` before committing (auto-fixes most issues)
- Pre-commit hooks will enforce these rules automatically

### TypeScript

**Configuration**: `tsconfig.json`

- Strict mode enabled (all strict type-checking options)
- `noUnusedLocals: true` - Error on unused local variables
- `noUnusedParameters: true` - Error on unused function parameters
- `noImplicitReturns: true` - Error when not all code paths return a value
- `noImplicitAny: true` - Error on implicit any types
- Path alias: `@/*` β†’ project root

### Git Hooks

**Husky 9.1.7 + lint-staged 16.2.3**

- **Pre-commit**: Runs Biome check on staged files (`.husky/pre-commit`)
- **Configuration**: `.lintstagedrc.json`
- Uses `pnpm lint-staged` command
- Automatically formats and fixes issues before commit
- Note: `prepare-commit-msg` hook removed (commitizen not installed)
- **Requires Node.js >= 20.17** (lint-staged v16 requirement)

## Important Notes

- **Routing**: Uses Next.js Pages Router (not App Router)
- **Testing**: No test framework configured (test script is a placeholder)
- **React**: Strict mode enabled in next.config.js
- **Dev Server**: Uses Turbopack for faster builds (`--turbopack` flag in dev script)
- **Package Manager**: Must use pnpm (not npm or yarn)
- **Node Version**: Requires Node.js >= 22.0.0
- **Deprecated Options**: `swcMinify` removed from next.config.js (enabled by default in Next.js 15)
- **Docker**: Pre-built images available at `danangekal/next-typescript-starter`
- **Biome vs ESLint/Prettier**: This project uses Biome exclusively - do not add ESLint or Prettier

## Migration Notes

This project was recently upgraded from:
- React 18 β†’ React 19
- Next.js 13 β†’ Next.js 15
- Node 16 β†’ Node 22
- Yarn β†’ pnpm
- ESLint + Prettier β†’ Biome
- Husky 8 β†’ Husky 9
22 changes: 14 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
# Set image from base on offical node lts alpine
ARG VERSION=lts-alpine
# Set image from base on official node 22 alpine
ARG VERSION=22-alpine
FROM node:$VERSION

# Set label maintainer, version & description
LABEL maintainer="[email protected]"
LABEL version="0.1.0"
LABEL description="Unofficial Next.js + Typescript starter with a latest package"

# Install pnpm
RUN corepack enable && corepack prepare pnpm@latest --activate

# Set working directory
WORKDIR /app

# Copy all files
COPY . .
# Copy package files
COPY package.json pnpm-lock.yaml ./

# Install dependencies
RUN yarn install --frozen-lockfile
RUN pnpm install --frozen-lockfile

# Copy all files
COPY . .

# Build app
RUN yarn build
RUN pnpm build

# Expose the listening port
EXPOSE 3000

# Run yarb start script when container starts
CMD yarn start
# Run pnpm start script when container starts
CMD pnpm start
Loading