Project Structure
Understanding the project structure will help you navigate and extend CraftJS effectively.
Overview
CraftJS follows a well-organized structure that separates concerns and makes it easy to find what you’re looking for.
- layout.tsx
- page.tsx
- env.ts
- proxy.ts
- drizzle.config.ts
- next.config.ts
- package.json
- tailwind.config.ts
- tsconfig.json
Directory Details
/src/app - Next.js App Router
The app directory contains all your routes using the Next.js App Router convention.
Route Groups
(auth)- Authentication pages (login, register, forgot password)(dashboard)- Protected dashboard pages that require authentication
Route groups (folders with parentheses) don’t affect the URL structure. They’re used for organization and sharing layouts.
API Routes
The api folder contains all backend API endpoints:
api/
├── auth/[...all]/route.ts # Better Auth handler
├── chat/route.ts # AI chat endpoint
└── webhooks/
└── dodo/route.ts # Payment webhooks/src/components - React Components
Organized by purpose:
| Folder | Purpose |
|---|---|
layout/ | Dashboard layout components (sidebar, header, footer) |
providers/ | React context providers (theme, query, etc.) |
settings/ | Settings page components |
ui/ | shadcn/ui components |
/src/lib - Business Logic
This is where the core functionality lives:
lib/ai/
AI-related code including model configuration, prompts, and custom tools.
// lib/ai/models.ts
export const models = {
"gpt-4o": openai("gpt-4o"),
"claude-sonnet-4": anthropic("claude-sonnet-4-20250514"),
"gemini-2-flash": google("gemini-2.0-flash"),
}lib/auth/
Better Auth configuration for both client and server.
lib/cache/
Redis client and rate limiting utilities.
lib/db/
Drizzle ORM client and database schema definitions.
lib/email/
Resend client and React Email templates.
lib/payments/
Dodo Payments integration and subscription plan definitions.
lib/storage/
Cloudflare R2 storage utilities.
lib/analytics/
PostHog client for product analytics.
/src/trigger - Background Jobs
Trigger.dev tasks for async processing:
// trigger/tasks.ts
export const sendWelcomeEmail = task({
id: "send-welcome-email",
run: async (payload: { userId: string }) => {
// Send email logic
},
})Key Files
env.ts
Environment variable validation using T3 Env:
export const env = createEnv({
server: {
DATABASE_URL: z.string().url(),
BETTER_AUTH_SECRET: z.string().min(32),
// ...
},
client: {
NEXT_PUBLIC_POSTHOG_KEY: z.string().optional(),
// ...
},
})proxy.ts
Next.js middleware for route protection:
export default defineMiddleware((request) => {
// Protect dashboard routes
// Redirect unauthenticated users to login
})Conventions
File Naming
- Components: PascalCase (
Button.tsx,UserProfile.tsx) - Utilities: camelCase (
formatDate.ts,parseQuery.ts) - Constants: SCREAMING_SNAKE_CASE for values, camelCase for files
Import Aliases
CraftJS uses path aliases for cleaner imports:
// Instead of
import { Button } from "../../../components/ui/button"
// Use
import { Button } from "@/components/ui/button"Colocation
Related files are colocated:
- Component + its styles
- Route + its loading/error states
- API route + its validation schema
Customization
Adding New Features
- New Route: Add a folder in
app/with apage.tsx - New API: Add a
route.tsinapp/api/ - New Component: Add to appropriate
components/subfolder - New Library: Add to
lib/with clear module boundaries
Removing Features
Each feature is self-contained. To remove:
- Delete the relevant folders/files
- Remove related environment variables
- Remove imports and usages
- Run
pnpm buildto check for broken imports
When removing features like payments or analytics, make sure to also remove the related provider wrappers in layout.tsx.