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 inglobals.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.