Cookbook

The Architech Cookbook

Quick recipes for common tasks. Copy, paste, adapt, done.


Recipe 1: Create Your First Project (60 Seconds)

Goal: Get a working Next.js app in 60 seconds with zero configuration.

Steps:

# 1. Install The Architech (one-time setup)
git clone https://github.com/the-architech-xyz/cli.git
cd cli && npm install && npm run build && npm link
 
# 2. Create project
architech new my-first-app --genome hello-world
 
# 3. Run it
cd my-first-app
npm install
npm run dev

Result: Next.js app running at http://localhost:3000 (opens in a new tab)

What you got: Next.js 15, TypeScript, Tailwind CSS, shadcn/ui, ESLint, Prettier


Recipe 2: Add a New Database Table

Goal: Add a products table to your Drizzle database.

Prerequisites: Project with database/drizzle adapter

Steps:

# 1. Create schema file
cat > src/lib/db/schema/products.ts << 'EOF'
import { pgTable, serial, text, integer, timestamp } from 'drizzle-orm/pg-core';
 
export const products = pgTable('products', {
  id: serial('id').primaryKey(),
  name: text('name').notNull(),
  description: text('description'),
  price: integer('price').notNull(), // in cents
  createdAt: timestamp('created_at').defaultNow().notNull(),
  updatedAt: timestamp('updated_at').defaultNow().notNull()
});
 
export type Product = typeof products.$inferSelect;
export type InsertProduct = typeof products.$inferInsert;
EOF
 
# 2. Export from schema index
echo "export * from './products.js';" >> src/lib/db/schema/index.ts
 
# 3. Generate migration
npm run db:generate
 
# 4. Push to database
npm run db:push

Result: New products table in your database, fully typed.

Next: The drizzle-nextjs connector will auto-generate:

  • /api/products route
  • useProducts() TanStack Query hook
  • Full CRUD operations

Recipe 3: Add GitHub OAuth to Authentication

Goal: Add GitHub login to your app.

Prerequisites: Project with auth/better-auth adapter

Steps:

# 1. Create GitHub OAuth App
# Go to: https://github.com/settings/developers
# Create new OAuth App
# Set callback: http://localhost:3000/api/auth/callback/github
# Copy Client ID and Client Secret
 
# 2. Add to .env
echo 'GITHUB_CLIENT_ID="your_github_client_id"' >> .env
echo 'GITHUB_CLIENT_SECRET="your_github_secret"' >> .env
 
# 3. Update auth config
cat > src/lib/auth/config.ts << 'EOF'
import { betterAuth } from 'better-auth';
 
export const authHandler = betterAuth({
  database: {
    provider: 'postgres',
    url: process.env.DATABASE_URL!
  },
  socialProviders: {
    github: {
      clientId: process.env.GITHUB_CLIENT_ID!,
      clientSecret: process.env.GITHUB_CLIENT_SECRET!,
    }
  }
});
EOF
 
# 4. Restart dev server
npm run dev

Result: GitHub OAuth button appears on login page.

Test: Click "Sign in with GitHub" → redirects to GitHub → returns authenticated.


Recipe 4: Create a Custom TanStack Query Hook

Goal: Create a reusable data-fetching hook following Golden Core patterns.

Use when: You have a custom API endpoint that doesn't use the database.

Steps:

// src/hooks/use-custom-data.ts
 
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
 
// Define your types
interface CustomData {
  id: string;
  value: string;
}
 
// Query keys for caching
const customDataKeys = {
  all: ['custom-data'] as const,
  detail: (id: string) => [...customDataKeys.all, id] as const,
};
 
/**
 * Fetch custom data
 */
export function useCustomData() {
  return useQuery({
    queryKey: customDataKeys.all,
    queryFn: async (): Promise<CustomData[]> => {
      const res = await fetch('/api/custom-data');
      if (!res.ok) throw new Error('Failed to fetch');
      return res.json();
    },
    staleTime: 5 * 60 * 1000, // 5 minutes
  });
}
 
/**
 * Create custom data
 */
export function useCreateCustomData() {
  const queryClient = useQueryClient();
  
  return useMutation({
    mutationFn: async (data: Omit<CustomData, 'id'>) => {
      const res = await fetch('/api/custom-data', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data),
      });
      if (!res.ok) throw new Error('Failed to create');
      return res.json();
    },
    onSuccess: () => {
      // Invalidate cache to show new data
      queryClient.invalidateQueries({ queryKey: customDataKeys.all });
    },
  });
}

Result: Golden Core compliant hook ready to use in any component.

Use it:

function MyComponent() {
  const { data, isLoading } = useCustomData();
  const createData = useCreateCustomData();
  
  // ... your UI
}

Recipe 5: Swap UI Library (shadcn → MUI)

Goal: Change UI library without touching business logic.

Prerequisites: Project using headless feature pattern

Steps:

This demonstrates the power of The Architech's architecture. Due to the Headless Logic + UI pattern, you only need to replace UI components, not hooks.

What stays the same:

  • All useTeams(), useAuth(), etc. hooks → unchanged
  • All business logic → unchanged
  • All API routes → unchanged
  • All database code → unchanged

What changes:

  • UI components only

Example:

// Before (shadcn/ui)
import { Button } from '@/components/ui/button';
import { Card } from '@/components/ui/card';
 
// After (MUI)
import { Button, Card } from '@mui/material';
 
// The hook stays exactly the same:
const { data: teams } = useTeams();  // ← No change needed!

Full swap (future feature):

# V2 feature (coming soon)
architech swap-ui --from shadcn --to mui

Recipe 6: Add Stripe Subscription Tiers

Goal: Add pricing tiers to your SaaS.

Prerequisites: Project with payment/stripe adapter

Steps:

// 1. Define tiers in src/lib/stripe/plans.ts
export const PLANS = [
  {
    id: 'free',
    name: 'Free',
    price: 0,
    features: ['5 projects', 'Basic support']
  },
  {
    id: 'pro',
    name: 'Pro',
    price: 1900, // $19.00 in cents
    priceId: 'price_xxx', // From Stripe dashboard
    features: ['Unlimited projects', 'Priority support', 'Advanced features']
  },
  {
    id: 'enterprise',
    name: 'Enterprise',
    price: 9900, // $99.00
    priceId: 'price_yyy',
    features: ['Everything in Pro', 'Custom SLA', 'Dedicated support']
  }
];
 
// 2. Create pricing page
// src/app/pricing/page.tsx
import { PLANS } from '@/lib/stripe/plans';
import { Button } from '@/components/ui/button';
 
export default function PricingPage() {
  return (
    <div className="container py-12">
      <h1 className="text-4xl font-bold text-center mb-12">Pricing</h1>
      <div className="grid md:grid-cols-3 gap-8">
        {PLANS.map(plan => (
          <div key={plan.id} className="border rounded-lg p-6">
            <h2 className="text-2xl font-bold">{plan.name}</h2>
            <p className="text-3xl font-bold my-4">
              ${plan.price / 100}/mo
            </p>
            <ul className="space-y-2 mb-6">
              {plan.features.map(feature => (
                <li key={feature}>✓ {feature}</li>
              ))}
            </ul>
            <Button className="w-full">
              {plan.price === 0 ? 'Start Free' : 'Subscribe'}
            </Button>
          </div>
        ))}
      </div>
    </div>
  );
}

Result: Beautiful pricing page with subscription options.


Recipe 7: Add Custom Environment Variables

Goal: Add new environment variables to your project.

Steps:

# 1. Add to .env
echo 'MY_CUSTOM_API_KEY="your_key_here"' >> .env
echo 'MY_CUSTOM_API_URL="https://api.example.com"' >> .env
 
# 2. Add to .env.example (for documentation)
echo 'MY_CUSTOM_API_KEY="your_api_key"' >> .env.example
echo 'MY_CUSTOM_API_URL="https://api.example.com"' >> .env.example
 
# 3. Use in code
// src/lib/custom-api.ts
export const customApi = {
  key: process.env.MY_CUSTOM_API_KEY,
  url: process.env.MY_CUSTOM_API_URL
};
 
# 4. Add TypeScript types (optional)
// src/env.d.ts
declare namespace NodeJS {
  interface ProcessEnv {
    MY_CUSTOM_API_KEY: string;
    MY_CUSTOM_API_URL: string;
  }
}

Result: Type-safe environment variables.


Recipe 8: Create a Simple Adapter

Goal: Create your first adapter to contribute to the marketplace.

Steps:

# 1. Create adapter directory
cd marketplace
mkdir -p adapters/utilities/dayjs
mkdir -p adapters/utilities/dayjs/templates
 
# 2. Create adapter.json
cat > adapters/utilities/dayjs/adapter.json << 'EOF'
{
  "id": "utilities/dayjs",
  "name": "Day.js",
  "description": "Lightweight date library",
  "category": "utilities",
  "version": "1.0.0",
  "provides": ["date-utilities", "dayjs"],
  "capabilities": {
    "date-utilities": {
      "version": "1.0.0",
      "description": "Date manipulation utilities"
    }
  },
  "dependencies": {
    "dayjs": "^1.11.0"
  }
}
EOF
 
# 3. Create blueprint.ts
cat > adapters/utilities/dayjs/blueprint.ts << 'EOF'
import { Blueprint, BlueprintActionType } from '@thearchitech.xyz/types';
 
export default function generateBlueprint(config: any) {
  return [
    // Create utility file
    {
      type: BlueprintActionType.CREATE_FILE,
      path: '{{paths.shared_library}}utils/date.ts',
      template: 'templates/date-utils.ts.tpl'
    }
  ];
}
EOF
 
# 4. Create template
cat > adapters/utilities/dayjs/templates/date-utils.ts.tpl << 'EOF'
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
 
dayjs.extend(relativeTime);
 
export { dayjs };
 
export function formatDate(date: string | Date): string {
  return dayjs(date).format('MMM D, YYYY');
}
 
export function fromNow(date: string | Date): string {
  return dayjs(date).fromNow();
}
EOF
 
# 5. Build marketplace
npm run build

Result: New adapter ready to use in genomes!

Test it:

// Add to a genome:
{
  id: 'utilities/dayjs',
  parameters: {}
}

Recipe 9: Debug a Generation Error

Goal: Figure out why generation failed.

Steps:

# 1. Run with verbose logging
architech new my-app --genome saas-starter --verbose
 
# 2. Check what would be created (without creating)
architech new my-app --genome saas-starter --dry-run
 
# 3. Verify genome file
cat marketplace/genomes/official/03-full-saas-platform.genome.ts
 
# 4. Check marketplace is built
cd marketplace
npm run build
 
# 5. Verify module exists
ls -la marketplace/adapters/framework/nextjs/
 
# 6. Check CLI version
architech --version
 
# 7. Check Node.js version
node --version  # Should be 18+

Common fixes:

  • Rebuild marketplace: cd marketplace && npm run build
  • Rebuild CLI: cd Architech && npm run build
  • Relink CLI: cd Architech && npm link

Recipe 10: Set Up Development Environment

Goal: Prepare for contributing to The Architech.

Steps:

# 1. Fork repositories
# Fork: github.com/the-architech-xyz/cli
# Fork: github.com/the-architech-xyz/marketplace
 
# 2. Clone your forks
git clone https://github.com/YOUR_USERNAME/cli.git architech-cli
git clone https://github.com/YOUR_USERNAME/marketplace.git architech-marketplace
 
# 3. Set up CLI
cd architech-cli
npm install
npm run build
npm link
 
# 4. Set up marketplace
cd ../architech-marketplace
npm install
npm run build
npm link
 
# 5. Link marketplace to CLI
cd ../architech-cli
npm link @thearchitech.xyz/marketplace
 
# 6. Verify setup
architech list-genomes  # Should list 6 genomes
 
# 7. Create test project
cd ..
architech new test-app --genome hello-world
 
# 8. Verify test project works
cd test-app
npm install
npm run dev

Result: Full development environment ready for contributing!


Recipe 11: Edit a Genome to Add Modules

Goal: Customize an existing genome for your needs.

Scenario: You want the hello-world genome but with database support.

Steps:

// 1. Copy official genome
cp marketplace/genomes/official/01-hello-world.genome.ts ./my-custom.genome.ts
 
// 2. Edit my-custom.genome.ts
import { defineGenome } from '@thearchitech.xyz/marketplace/types';
 
export default defineGenome({
  version: '1.0.0',
  project: {
    name: 'my-custom-app',
    framework: 'nextjs',
  },
  modules: [
    // Keep original modules
    { id: 'framework/nextjs', parameters: { typescript: true, tailwind: true } },
    { id: 'ui/shadcn-ui', parameters: { theme: 'default' } },
    
    // ADD: Database support
    {
      id: 'database/drizzle',
      parameters: {
        provider: 'neon',
        databaseType: 'postgresql',
        features: { migrations: true, studio: true }
      }
    },
    
    // ADD: TanStack Query for data fetching
    {
      id: 'data-fetching/tanstack-query',
      parameters: { devtools: true }
    },
    
    // ADD: Drizzle-Next.js connector
    {
      id: 'connectors/tanstack-query-nextjs',
      parameters: {}
    }
  ]
});
# 3. Generate from custom genome
architech new my-app --genome ./my-custom.genome.ts
 
# Or make it available as alias
architech config add-alias my-custom ./my-custom.genome.ts
architech new my-app --genome my-custom

Result: Custom genome with exactly what you need!


Recipe 12: Add Sentry Error Tracking

Goal: Add production error monitoring.

Prerequisites: Running Next.js project

Steps:

# 1. Sign up at sentry.io
# 2. Create new project
# 3. Copy DSN
 
# 4. Add to .env
echo 'SENTRY_DSN="https://xxx@xxx.ingest.sentry.io/xxx"' >> .env
echo 'NEXT_PUBLIC_SENTRY_DSN="https://xxx@xxx.ingest.sentry.io/xxx"' >> .env
 
# 5. If not in genome, manually install
npm install @sentry/nextjs
 
# 6. Initialize Sentry
npx @sentry/wizard@latest -i nextjs
 
# 7. Test error tracking
# Add to any page:
<button onClick={() => { throw new Error('Test error'); }}>
  Test Sentry
</button>
 
# 8. Check Sentry dashboard
# Errors should appear in dashboard

Result: All errors tracked in Sentry dashboard.

Better way: Include in genome from the start:

{ id: 'observability/sentry', parameters: { features: { errorTracking: true } } }

Recipe 13: Create a Zustand Store

Goal: Add global state management following Golden Core patterns.

Prerequisites: Project with state/zustand adapter

Steps:

// src/stores/ui-store.ts
 
import { create } from 'zustand';
import { immer } from 'zustand/middleware/immer';
 
interface UIState {
  // State
  isSidebarOpen: boolean;
  theme: 'light' | 'dark';
  
  // Actions
  toggleSidebar: () => void;
  setTheme: (theme: 'light' | 'dark') => void;
}
 
export const useUIStore = create<UIState>()(
  immer((set) => ({
    // Initial state
    isSidebarOpen: true,
    theme: 'light',
    
    // Actions
    toggleSidebar: () => set((state) => {
      state.isSidebarOpen = !state.isSidebarOpen;
    }),
    
    setTheme: (theme) => set((state) => {
      state.theme = theme;
    }),
  }))
);

Use it:

function Sidebar() {
  const isSidebarOpen = useUIStore(state => state.isSidebarOpen);
  const toggleSidebar = useUIStore(state => state.toggleSidebar);
  
  return (
    <div className={isSidebarOpen ? 'block' : 'hidden'}>
      <button onClick={toggleSidebar}>Toggle</button>
      {/* sidebar content */}
    </div>
  );
}

Result: Global UI state with zero boilerplate!


Recipe 14: Add Tests for a Feature

Goal: Write tests for generated features.

Prerequisites: Project with testing/vitest adapter

Steps:

// __tests__/features/teams.test.ts
 
import { renderHook, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { useTeams, useCreateTeam } from '@/hooks/use-teams';
 
// Setup
const createWrapper = () => {
  const queryClient = new QueryClient();
  return ({ children }: { children: React.ReactNode }) => (
    <QueryClientProvider client={queryClient}>
      {children}
    </QueryClientProvider>
  );
};
 
describe('Teams Feature', () => {
  it('should fetch teams', async () => {
    const { result } = renderHook(() => useTeams(), {
      wrapper: createWrapper()
    });
 
    await waitFor(() => {
      expect(result.current.data).toBeDefined();
    });
  });
 
  it('should create team', async () => {
    const { result } = renderHook(() => useCreateTeam(), {
      wrapper: createWrapper()
    });
 
    act(() => {
      result.current.mutate({ name: 'Test Team' });
    });
 
    await waitFor(() => {
      expect(result.current.isSuccess).toBe(true);
    });
  });
});
# Run tests
npm run test
 
# With coverage
npm run test:coverage

Result: Tested features with confidence!


Recipe 15: Deploy to Vercel

Goal: Deploy your generated project to production.

Prerequisites: Project with deployment/vercel adapter

Steps:

# 1. Install Vercel CLI
npm install -g vercel
 
# 2. Login
vercel login
 
# 3. Deploy
vercel
 
# 4. Add environment variables in Vercel dashboard
# Go to: vercel.com/your-project/settings/environment-variables
# Add all variables from .env
 
# 5. Redeploy with production env vars
vercel --prod

Or use GitHub integration:

# 1. Push to GitHub
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/you/repo.git
git push -u origin main
 
# 2. Import in Vercel
# vercel.com/new → Import from GitHub
 
# 3. Add environment variables in dashboard
 
# 4. Deploy
# Automatic on every push to main

Result: Production app at https://your-app.vercel.app (opens in a new tab)


Quick Tips

Speed up generation

// In genome, skip npm install
options: {
  skipInstall: true
}
// Then manually: npm install

Use dry-run before generating

architech new my-app --genome saas-starter --dry-run

Interactive genome picker

architech new my-app  # No --genome flag = shows picker

List genomes by category

architech list-genomes --search ai
architech list-genomes --complexity simple

Check generated file structure

architech new my-app --genome saas-starter --dry-run --verbose

Need more recipes? Join Discord (opens in a new tab) and ask the community!