next-starter

repository·main·Indexed 21 days ago

https://github.com/skolaczk/next-starter

A production-ready Next.js 15 starter template featuring React 19, Tailwind CSS 4, and a suite of tools for authentication, payments, and testing. It includes Drizzle ORM with PostgreSQL, NextAuth for authentication, Stripe for payments, and Playwright for end-to-end testing. The template provides pre-configured components for theme switching, authentication controls, and environment variable validation using zod and @t3-oss/env-nextjs.

Tokens
7K
Snippets
23
Records
25
Agent score
74%

What's inside next-starter

  1. Project Structure Overview

    main

    The project follows a standard Next.js App Router structure with specific directories for logic and testing:

    • src/app: Next.js App Router pages and layouts.
    • src/actions: Server Actions.
    • src/components: React components.
    • src/lib: Utility functions and shared logic.
    • src/styles: Global and component styles.
    • src/env.mjs: Environment variable configuration (managed via t3-env).
    • src/__tests__: Unit and end-to-end (e2e) tests.
    • public/: Static assets.
    • .husky/: Git hook configurations.
    • prisma/: Prisma schema and migrations (Note: The project also lists Drizzle as a feature, check your specific version's configuration).
    .
    ├── .github                         # GitHub folder
    ├── .husky                          # Husky configuration
    ├── prisma                          # Prisma schema and migrations
    ├── public                          # Public assets folder
    └── src
        ├── __tests__                   # Unit and e2e tests
        ├── actions                     # Server actions
        ├── app                         # Next JS App (App Router)
        ├── components                  # React components
        ├── lib                         # Functions and utilities
        ├── styles                      # Styles folder
        └── env.mjs                     # Env variables config file
  2. Quickstart: Clone, Install, and Run the Starter Template

    main

    Follow these steps to set up a new project using the next-starter template:

    1. Clone the template (choose one method):
      • Use the GitHub "Use this template" button.
      • Use create-next-app:
        npx create-next-app -e https://github.com/Skolaczk/next-starter my-project-name
      • Use git clone:
        git clone https://github.com/Skolaczk/next-starter my-project-name
    2. Install dependencies:
      npm install
    3. Set up environment variables: Create a .env file in the root directory and populate it with the required variables found in .env.example.
    4. Prepare Husky (required for Git hooks to work):
      npm run prepare
    5. Run the development server:
      npm run dev
      The app will be available at http://localhost:3000/.
    npx create-next-app -e https://github.com/Skolaczk/next-starter my-project-name
  3. Configure Playwright E2E testing

    main

    The project uses Playwright for end-to-end (E2E) testing. Tests are located in ./src/__tests__/e2e. The configuration is optimized for both local development and CI environments:

    • Parallelism: Tests run in parallel (fullyParallel: true). On CI, workers are limited to 1 to prevent resource contention.
    • Retries: Tests retry up to 2 times on CI, but 0 times locally.
    • CI Safety: The forbidOnly flag is enabled on CI to prevent accidental commits containing test.only.
    • Reporting: Uses the html reporter.
    • Base URL: The default baseURL is set to http://127.0.0.1:3000.
    export default defineConfig({
      testDir: "./src/__tests__/e2e",
      fullyParallel: true,
      forbidOnly: !!process.env.CI,
      retries: process.env.CI ? 2 : 0,
      workers: process.env.CI ? 1 : undefined,
      reporter: "html",
      use: {
        baseURL: "http://127.0.0.1:3000",
        trace: "on-first-retry",
      },
    });
  4. Configure Prettier with Tailwind CSS plugin

    main

    The project uses prettier-plugin-tailwindcss to automatically sort Tailwind CSS classes. This plugin is configured via the prettier.config.js file. To ensure consistent class ordering, ensure this plugin is included in your Prettier configuration.

    module.exports = {
      plugins: ["prettier-plugin-tailwindcss"],
    };
  5. Configure ESLint with Next.js and Accessibility rules

    main

    The project uses the ESLint Flat Config format via @eslint/eslintrc's FlatCompat to maintain compatibility with existing Next.js and plugin configurations. The configuration includes:

    • Next.js Core Web Vitals: next/core-web-vitals
    • TypeScript Support: next/typescript
    • Prettier Integration: prettier (to disable conflicting rules)
    • Accessibility: plugin:jsx-a11y/recommended for JSX accessibility checks
    • Import Sorting: simple-import-sort plugin is enabled to enforce consistent ordering of imports and exports.

    Rules for import/export sorting are set to warn level.

    import { FlatCompat } from "@eslint/eslintrc";
    import { dirname } from "path";
    import { fileURLToPath } from "url";
    
    const __filename = fileURLToPath(import.meta.url);
    const __dirname = dirname(__filename);
    
    const compat = new FlatCompat({
      baseDirectory: __dirname,
    });
    
    const eslintConfig = [
      ...compat.config({
        extends: [
          "next/core-web-vitals",
          "next/typescript",
          "prettier",
          "plugin:jsx-a11y/recommended",
        ],
        plugins: ["simple-import-sort"],
        rules: {
          "simple-import-sort/imports": "warn",
          "simple-import-sort/exports": "warn",
        },
      }),
    ];
    
    export default eslintConfig;
  6. Configure internationalization routing in middleware

    main

    The project uses next-intl to handle internationalization (i18n) routing. The middleware is initialized using createMiddleware from next-intl/middleware, passing in a routing configuration object imported from ./i18n/routing. This middleware intercepts requests to manage locale-based routing and redirects.

    To customize the available locales or routing behavior, you must modify the routing object in ./i18n/routing.ts rather than this middleware file.

    import createMiddleware from "next-intl/middleware";
    import { routing } from "./i18n/routing";
    
    export default createMiddleware(routing);
  7. Configure global site metadata via siteConfig

    main

    The siteConfig object in src/lib/site-config.ts is the central location for defining global site metadata used for SEO and site identification. You can customize the site title, description, keywords, and URL. Note that url and googleSiteVerificationId are driven by environment variables.

    export const siteConfig = {
      title: "Next.js Starter",
      description: "A Next.js starter template...",
      keywords: ["Next.js", "TypeScript", "Tailwind CSS", "Next-auth"],
      url: env.APP_URL,
      googleSiteVerificationId: env.GOOGLE_SITE_VERIFICATION_ID || "",
    };
  8. Configure Drizzle ORM with PostgreSQL

    main

    The project uses drizzle-kit for database schema management and migrations. The configuration is defined in drizzle.config.ts and specifies the database dialect, the location of the schema file, and the connection credentials. It relies on the DATABASE_URL environment variable (accessed via the @/env.mjs module) to provide the connection string.

    import { defineConfig } from "drizzle-kit";
    import { env } from "@/env.mjs";
    
    export default defineConfig({
      dialect: "postgresql",
      schema: "./src/lib/schema.ts",
      dbCredentials: {
        url: env.DATABASE_URL,
      },
    });
  9. Configure the Playwright web server

    main

    To ensure tests run against a live application, Playwright is configured to manage a local development server.

    • Command: Runs npm run dev to start the server.
    • URL: Monitors http://127.0.0.1:3000 to know when the server is ready.
    • Reuse: On local machines, it will reuseExistingServer if one is already running, whereas on CI it will always start a fresh instance.
    webServer: {
      command: "npm run dev",
      url: "http://127.0.0.1:3000",
      reuseExistingServer: !process.env.CI,
    }
  10. Available NPM Scripts

    main

    Use these scripts to manage development, testing, and building:

    ScriptDescription
    devRun development server
    buildBuild the application for production
    startRun the production server
    previewRun build and start commands together
    lintLint the code using Eslint
    lint:fixFix linting errors automatically
    format:checkCheck code for proper formatting
    format:writeFix formatting issues
    typecheckType-check TypeScript without emitting files
    testRun unit tests
    test:watchRun unit tests in watch mode
    e2eRun end-to-end tests
    e2e:uiRun end-to-end tests with UI
    postbuildGenerate sitemap
    prepareInstall Husky for managing Git hooks
  11. Use exported auth methods for authentication

    main

    The src/lib/auth.ts module exports the core NextAuth primitives required to manage user sessions and authentication state in the application. You can use these methods to trigger sign-in/sign-out flows or to protect routes and access session data.

    Available exports:

    • auth: Used to retrieve the session in Server Components, Middleware, or API routes.
    • handlers: The GET and POST handlers for NextAuth API routes.
    • signIn: Function to initiate a sign-in process.
    • signOut: Function to initiate a sign-out process.
    import { auth, signIn, signOut } from "@/lib/auth";
    
    // Example: Accessing session in a Server Component
    const session = await auth();
    
    // Example: Triggering sign in
    await signIn("github");
    
    // Example: Triggering sign out
    await signOut();