Back to blog
·6 min read

How to Structure Next.js and Supabase Projects with Claude Code Without Burning Your Context Window

Building with Claude Code and Supabase is powerful, but without the right structure, you'll burn through your context window in hours and end up with performance nightmares. Here's the production-ready approach developers are actually using.

How to Structure Next.js and Supabase Projects with Claude Code Without Burning Your Context Window

You're working with Claude Code to scaffold your Next.js and Supabase application. You write one complex prompt. Claude spins up a beautiful architecture. Then you check your token usage: 50-70% of your weekly limit is gone. Two more prompts and you're locked out until Monday.

This isn't a flaw in Claude Code. This is a flaw in how most developers approach AI-assisted development without a clear project structure.

The real problem: when your codebase lacks intentional organization, every prompt to Claude requires the AI to re-analyze your entire project structure just to understand what's already been built. You end up with MCP servers pulling your entire database schema, your full component tree, and every utility function into the context window—even when Claude only needs to see one folder.

The solution isn't less ambition. It's deliberate structure that lets Claude Code work smarter, not harder.

The Three Layers of Next.js + Supabase Architecture

Production-ready Next.js and Supabase projects follow a specific organizational pattern. Not because it's trendy, but because it's the only pattern that scales with AI-assisted development.

### Layer 1: Feature-Based Folder Structure

Stop organizing by file type. Stop putting all components in one massive folder. Stop shoving business logic into page.tsx files.

Instead, organize by feature:

```

app/

(auth)/

login/

signup/

forgot-password/

(dashboard)/

[userId]/

settings/

billing/

team/

api/

auth/

users/

lib/

supabase/

client.ts

server.ts

admin.ts

hooks/

db/

components/

shared/

```

Each feature folder contains everything that feature needs: its page, its components, its server actions, its types. This matters for Claude Code because when you ask Claude to "add a billing page," it knows exactly where billing code lives. Claude doesn't need to scan your entire codebase. The context window stays small.

The biggest mistake developers make: putting all code in the app directory. Resist this. Keep app/ for Next.js routing only. Move actual business logic, hooks, and database queries into lib/, components/, and feature folders. Pages should be thin—mostly composition and Next.js metadata.

### Layer 2: Supabase Authentication as a Separate Concern

This is where most tutorials fail. They show you a quick login form in page.tsx and call it done. Production code needs the Supabase SSR helper, middleware for protecting routes, and clear separation between client and server operations.

Create a dedicated auth structure:

```

lib/supabase/

client.ts // Client-side Supabase instance

server.ts // Server component/action instance

admin.ts // Admin client (never expose to browser)

auth.ts // Auth helper functions

middleware.ts // Route protection

```

The client.ts file handles browser-side operations. The server.ts handles SSR and server actions. The admin.ts never touches the browser. This separation prevents the chaos where Claude generates code that tries to use the admin client in client components, or worse, hardcodes secrets.

When you ask Claude to generate an auth flow, specify the file where it should live. This single decision prevents context bloat because Claude understands the boundaries immediately.

Context Window Management: The /context Command

Claude Code includes a /context command that most developers don't know about. It prevents exactly the problem you're experiencing.

Inside a Claude Code session, run /context to see what's eating your token budget. You'll often find MCP servers pulling massive database schemas, your entire git history, or every file in your components folder.

Use this workflow:

  • Before starting a complex feature, run /context in Claude
  • Look for what's loaded that you don't need
  • Use file exclusions in your workspace settings to prevent MCP servers from pulling irrelevant files
  • For Supabase specifically, create a schema.sql file that documents your tables without pulling the entire database
  • This single practice cuts context consumption by 50-70% in real projects.

    Preventing N+1 Query Disasters

    The other reason structure matters: preventing N+1 queries. When Claude sees your entire codebase at once, it gets creative in dangerous ways. It might fetch posts, then fetch authors individually. Performance tanks.

    Create a queries/ folder with explicit query patterns:

    ```

    lib/db/

    queries/

    posts.ts // All post queries

    users.ts // All user queries

    authors.ts // Preloaded author relationships

    ```

    In posts.ts, define queries with relationships preloaded:

    ```

    export async function getPostsWithAuthors(supabase: SupabaseClient) {

    return supabase

    .from('posts')

    .select('*, authors(id, name, avatar)')

    .order('created_at', { ascending: false });

    }

    ```

    When you ask Claude to "fetch posts for the dashboard," point it to this queries/ folder. Claude won't invent N+1 queries because the pattern is already there. It just uses the existing function.

    The Workflow: Asking Claude Code the Right Way

    Structure enables better prompts. Here's what actually works:

    Instead of: "Build me a billing page with Supabase and Next.js"

    Use: "Add a billing page in app/(dashboard)/[userId]/billing following the pattern in app/(dashboard)/[userId]/settings. Use queries from lib/db/queries/billing.ts. Protect the route with the auth middleware from lib/supabase/middleware.ts."

    The difference? The second prompt tells Claude exactly where to look and what patterns to follow. Claude doesn't need to analyze your entire project. Context window stays manageable. The code stays consistent.

    Tools That Help: ZipBuild and Similar Scaffolding

    If you're starting from scratch, this structure takes time to set up correctly. Scaffolding tools like ZipBuild automate this foundation. They generate Next.js and Supabase projects with this exact structure already in place, authentication configured, and database queries organized—so your first prompt to Claude Code isn't building the house, it's decorating rooms that already exist.

    The benefit: you start with low context consumption because the structure is intentional from day one.

    One More Pattern: Type Safety

    Define types explicitly in a types/ folder that Claude can reference:

    ```

    types/

    database.ts // Generated from Supabase schema

    api.ts // API response types

    domain.ts // Business logic types

    ```

    When Claude generates code, it references these types. No surprise data shapes. No context wasted on figuring out what properties exist. TypeScript prevents the messy code that often comes from AI assistance.

    Summary: Structure Before Prompts

    The developers who stay under their Claude Code token budget don't use fewer features. They use intentional structure that lets Claude work efficiently. Feature-based folders. Separated auth concerns. Explicit query patterns. File exclusions to prevent context bloat.

    This isn't overthinking. It's the only way AI-assisted development scales to production quality.

    Your next Next.js and Supabase project should start with this structure before you write a single prompt to Claude Code. It won't just save tokens—it'll make your code more maintainable, your performance better, and your AI assistance actually useful.

    Try the free discovery chat at zipbuild.dev to see how production-ready scaffolding with this structure built-in can jumpstart your project.

    Written by ZipBuild Team

    Ready to build with structure?

    Try the free discovery chat and see how ZipBuild architects your idea.

    Start Building