Project Structure

Understanding the layout of a matt-init project



Use the following checkboxes to toggle the flags you've selected in your project.

Toggle Features

my-project/
β”œβ”€β”€ .env
β”œβ”€β”€ .env.example
β”œβ”€β”€ .gitignore
β”œβ”€β”€ .vscode/
β”‚   β”œβ”€β”€ extensions.json
β”‚   └── settings.json
β”œβ”€β”€ drizzle.config.ts
β”œβ”€β”€ eslint.config.mjs
β”œβ”€β”€ flake.lock
β”œβ”€β”€ flake.nix
β”œβ”€β”€ next-env.d.ts
β”œβ”€β”€ next.config.ts
β”œβ”€β”€ package.json
β”œβ”€β”€ postcss.config.mjs
β”œβ”€β”€ tsconfig.json
β”œβ”€β”€ nix/
β”‚   └── devShell.nix
└── src/
    β”œβ”€β”€ app/
    β”‚   β”œβ”€β”€ globals.css
    β”‚   β”œβ”€β”€ layout.tsx
    β”‚   β”œβ”€β”€ page.tsx
    β”‚   β”œβ”€β”€ api/
    β”‚   β”‚   └── auth/
    β”‚   β”‚       └── [...all]/
    β”‚   β”‚           └── route.ts
    β”‚   β”œβ”€β”€ dashboard/
    β”‚   β”‚   └── page.tsx
    β”‚   β”œβ”€β”€ signin/
    β”‚   β”‚   └── page.tsx
    β”‚   └── signup/
    β”‚       └── page.tsx
    β”œβ”€β”€ components/
    β”‚   └── matt-init-banner.tsx
    β”œβ”€β”€ lib/
    β”‚   β”œβ”€β”€ auth.ts
    β”‚   β”œβ”€β”€ env.ts
    β”‚   β”œβ”€β”€ try-parse-env.ts
    β”‚   └── db/
    β”‚       β”œβ”€β”€ index.ts
    β”‚       └── schema/
    β”‚           β”œβ”€β”€ auth.ts
    β”‚           └── index.ts
    └── middleware.ts

Project Structure (Top-Level Files)

.env

This file contains environment variables needed for local development. It's dynamically generated when the project is scaffolded, based on your selected options (e.g. database, auth). It's also type-checked at runtime using Zod. You'll usually only need to touch this when deploying to production or if you're pointing to a different database or auth server.


.env.example

A template file showing the structure of environment variables needed by your application. This file is safe to commit to version control and helps other developers understand what environment variables they need to set up. When backend features are enabled, this file includes placeholder values for database URLs and authentication secrets.


drizzle.config.ts

This is the config file for Drizzle ORM. It sets the output folder for migration files, points to your schema, and defines your database dialect and credentials. The DB credentials are pulled directly from your .env file, so you won't hardcode any sensitive info here. If you later change your schema path or DB backend, update this file accordingly.


eslint.config.mjs

Your linting rules live here. It uses @antfu/eslint-config as a base, which includes solid defaults for React, TypeScript, and formatting. There are a few opinionated overrides: sorted imports, kebab-case filenames, and no top-level awaitβ€”intended to keep things consistent in team environments. You'll almost never need to touch this unless you strongly disagree with a specific rule (which is fair).


next-env.d.ts

This is managed by Next.js and used to make TypeScript play nice with your Next.js app. You should leave this file alone.


next.config.ts

Optional config file for customizing Next.js behavior. This project uses it to pre-load your environment variables on boot, so any invalid or missing envs will fail fast. If you want to tweak routing, image handling, or experimental flags, this is where you'd do it.


package.json

This file manages your project's metadata, dependencies, and scripts. It comes with all the essentials already set up: dev scripts, Drizzle DB commands, linting, and Tailwind. The dev script uses concurrently to run the Next.js dev server and the Turso dev server at the same time. If you add new CLI tooling or frameworks later, this is one of the first files you'll touch.


postcss.config.mjs

Tailwind uses PostCSS under the hood for its transformation pipeline. This config just loads the Tailwind plugin. You probably won't need to touch this.

Note: This project uses Tailwind CSS v4, which doesn't require a separate tailwind.config.ts file. Configuration is handled through CSS variables and @import statements in globals.css.


tsconfig.json

The TypeScript config includes sane defaults for a modern React project. It enables some type checking, supports module aliasing (~/lib/env instead of ../../../lib/env), and is tailored for Next.js. If you add new folders or want to tweak compiler behavior, you'll adjust this file.

Note: The import alias is ~/, not @/. This is a personal preference, and you are more than welcome to change it to @/ if you prefer that style.


flake.nix

This is your project's Nix flake, defining its dependencies and build environments. If you're using Nix, this is what makes your dev shell reproducible. It pulls in specific versions of nodejs, pnpm, any database requirements if enabled, and other tools, so you don't have to worry about local mismatches between teammates. If you're not using Nix, you should be.


nix/devShell.nix

This file defines your Nix development shell. It specifies the Node.js version, PNPM, and any additional tools you want available in your dev environment (like jq, sqlite-utils, etc.). If you need to add or change tools, this is where you'd do it.


flake.lock

Autogenerated by Nix. It pins the exact versions of your flake dependencies (nixpkgs, flake-utils, etc.) to ensure reproducible builds across machines. You should commit this file. You should not edit this file.


.vscode/

If you opted in, these files are generated:

  • extensions.json: Recommended extensions for the stack (e.g., ESLint, Tailwind CSS IntelliSense, etc).
  • settings.json: Preconfigured formatting, import sorting, and TypeScript settings.

src/

All the application code lives here. Traditionally, Next.js projects scatter all this in the root, but this keeps things organized and modular.

app/

matt-init uses the Next.js App Router layout for file-based routing.

  • globals.css: Tailwind base styles and dark mode variables.
  • layout.tsx: Global layout with font imports and wrapper markup.
  • page.tsx: Simple home page with call-to-actions.

Additionally, if a backend is enabled, it includes:

  • api/auth/[...all]/route.ts: BetterAuth's Next.js handler route.
  • dashboard/page.tsx: A protected route showing auth and DB in action.
  • signin/ and signup/: Basic auth forms using BetterAuth's API.

components/

  • matt-init-banner.tsx: ASCII banner, purely decorative.

lib/

  • env.ts: Loads and validates environment variables using Zod.
  • try-parse-env.ts: Helper that throws if required env vars are missing.

And, if a backend is enabled:

  • auth.ts: Configures BetterAuth with Drizzle + SQLite.
  • db/: Drizzle ORM setup and schema.
    • index.ts: Connects to the DB using libSQL.
    • schema/: Prebuilt tables for user, session, etc.

middleware.ts

If a backend is enabled, this file contains the middleware for protecting routes like /dashboard. It checks if the user is authenticated and redirects unauthenticated users to the sign-in page. If you want to add more protected routes, you can extend this middleware logic.

Next Steps