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 devResult: 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:pushResult: New products table in your database, fully typed.
Next: The drizzle-nextjs connector will auto-generate:
/api/productsrouteuseProducts()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 devResult: 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 muiRecipe 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 buildResult: 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 devResult: 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-customResult: 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 dashboardResult: 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:coverageResult: 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 --prodOr 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 mainResult: 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 installUse dry-run before generating
architech new my-app --genome saas-starter --dry-runInteractive genome picker
architech new my-app # No --genome flag = shows pickerList genomes by category
architech list-genomes --search ai
architech list-genomes --complexity simpleCheck generated file structure
architech new my-app --genome saas-starter --dry-run --verboseNeed more recipes? Join Discord (opens in a new tab) and ask the community!