🦧 The Orangutan Kit
A dead-simple guide to setting up a modern dev toolkit. Next.js · Supabase or Convex · Resend · Mastra · Claude Code
What Is This?
This is a no-fluff setup guide for a full-stack TypeScript project with AI tooling baked in. Every tool here was picked because it's well-documented, has a generous free tier, and plays nicely with the others.
The stack at a glance:
| Layer | Tool | One-liner |
|---|---|---|
| Frontend + API | Next.js 15 | React framework with file-based routing and server rendering |
| Database | Supabase or Convex | Pick one. Supabase = Postgres + auth. Convex = real-time NoSQL |
| Resend | Send emails using React components as templates | |
| AI Framework | Mastra | Build AI agents, workflows, and RAG in TypeScript |
| Coding Agent | Claude Code | AI pair programmer in your terminal and IDE |
| Glue Layer | MCP Servers | Let Claude talk directly to your database and docs |
Before You Start
You need these installed:
- Node.js 20+ → nodejs.org
- Git → configured with your GitHub account
- Cursor IDE (recommended) or VS Code
You need these accounts (all have free tiers):
- Supabase → supabase.com (if choosing Supabase)
- Convex → convex.dev (if choosing Convex)
- Resend → resend.com — grab an API key
- Anthropic → console.anthropic.com — need Claude Pro/Max or API credits
Step 1 → Create Your Next.js Project
This is your foundation. Everything else plugs into this.
1npx create-next-app@latest orangutan-appAccept all the defaults (TypeScript, Tailwind, App Router, Turbopack). Then:
1cd orangutan-app
2npm run devOpen http://localhost:3000. You should see the welcome page. That's it — you have a working app.
What you need to know:
src/app/page.tsx→ your homepagesrc/app/layout.tsx→ wraps every page (put providers here)src/app/api/→ your API routes (serverless functions).env.local→ secrets go here (gitignored automatically)- Components are Server Components by default. Only add
"use client"when you need browser stuff (hooks, click handlers, etc.)
Step 2 → Pick Your Database
Option A: Supabase (Postgres, built-in auth)
Best if: you want SQL, row-level security, and built-in authentication.
1npm install @supabase/supabase-js @supabase/ssrAdd to .env.local:
1NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
2NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key(Find these in your Supabase dashboard → Settings → API, or the Connect dialog.)
Create src/lib/supabase/client.ts (for browser/client components):
1import { createBrowserClient } from "@supabase/ssr";
2
3export function createClient() {
4 return createBrowserClient(
5 process.env.NEXT_PUBLIC_SUPABASE_URL!,
6 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
7 );
8}Create src/lib/supabase/server.ts (for server components and API routes):
1import { createServerClient } from "@supabase/ssr";
2import { cookies } from "next/headers";
3
4export async function createClient() {
5 const cookieStore = await cookies();
6 return createServerClient(
7 process.env.NEXT_PUBLIC_SUPABASE_URL!,
8 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
9 { cookies: { /* see Supabase SSR docs for cookie handlers */ } }
10 );
11}Shortcut: Run
npx create-next-app -e with-supabaseto get a pre-wired starter with auth, middleware, and both clients already configured.
Option B: Convex (real-time NoSQL, TypeScript-native)
Best if: you want reactive queries, zero SQL, and everything in TypeScript.
1npm install convex
2npx convex devThis logs you in via GitHub, creates your project, and generates a convex/ folder. Keep this terminal running — it live-syncs your backend.
Create src/app/ConvexClientProvider.tsx:
1"use client";
2import { ConvexProvider, ConvexReactClient } from "convex/react";
3
4const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
5
6export default function ConvexClientProvider({
7 children,
8}: {
9 children: React.ReactNode;
10}) {
11 return <ConvexProvider client={convex}>{children}</ConvexProvider>;
12}Wrap your app in layout.tsx with this provider. Write queries in convex/ and use them with useQuery() from convex/react.
Step 3 → Email with Resend
1npm install resend @react-email/componentsAdd to .env.local:
1RESEND_API_KEY=re_your_api_key_hereCreate a template — src/components/email-template.tsx:
1export function WelcomeEmail({ name }: { name: string }) {
2 return (
3 <div>
4 <h1>Welcome, {name}!</h1>
5 <p>Thanks for joining.</p>
6 </div>
7 );
8}Create an API route — src/app/api/send/route.ts:
1import { Resend } from "resend";
2import { WelcomeEmail } from "@/components/email-template";
3
4const resend = new Resend(process.env.RESEND_API_KEY);
5
6export async function POST() {
7 const { data, error } = await resend.emails.send({
8 from: "Orangutan Kit <onboarding@resend.dev>",
9 to: ["your@email.com"],
10 subject: "Welcome!",
11 react: WelcomeEmail({ name: "Friend" }),
12 });
13 if (error) return Response.json({ error }, { status: 500 });
14 return Response.json(data);
15}Note: On the free tier, you can send to your own email from
onboarding@resend.dev— no domain setup needed for testing.
Step 4 → AI with Mastra
Mastra is a TypeScript framework for AI agents. Built on Vercel's AI SDK, supports 40+ providers.
Standalone project:
1npm create mastra@latestOr add to your existing Next.js app:
1npm install @mastra/core @ai-sdk/anthropicCreate your first agent — src/mastra/agents/index.ts:
1import { Agent } from "@mastra/core/agent";
2import { anthropic } from "@ai-sdk/anthropic";
3
4export const myAgent = new Agent({
5 name: "Orangutan Assistant",
6 instructions: "You are a helpful assistant for the Orangutan Kit project.",
7 model: anthropic("claude-sonnet-4-20250514"),
8});Test it locally:
1npx mastra devThis starts a playground at http://localhost:4111 where you can chat with your agent before wiring it into your app.
To use in Next.js: Mastra provides handleChatStream() for API routes and works with Vercel AI SDK's useChat() hook on the frontend.
Step 5 → Install Claude Code
Claude Code is an AI coding agent that lives in your terminal. It reads your codebase, edits files, runs commands, and manages git.
Terminal install
1npm install -g @anthropic-ai/claude-code
2cd orangutan-app
3claudeFirst run opens a browser to authenticate. After that, you're in.
In Cursor IDE
Easiest way: Open the Extensions panel → search "Claude Code" → install the official Anthropic extension → click the Claude icon to log in.
If that fails: Install manually:
1cursor --install-extension ~/.claude/local/node_modules/@anthropic-ai/claude-code/vendor/claude-code.vsixOr just use the terminal: Open Cursor's integrated terminal and run claude. Type /ide if it doesn't auto-detect Cursor.
Commands you'll actually use
| Command | What it does |
|---|---|
/init | Generate a CLAUDE.md for your project |
/compact | Compress context when conversation gets long |
/clear | Hard reset for a new task |
/model | Switch models (Sonnet, Opus, Haiku) |
/ide | Connect to your IDE from external terminal |
/cost | Check token usage |
Step 6 → Set Up MCP Servers
MCP (Model Context Protocol) lets Claude talk directly to your tools. Instead of copy-pasting database schemas or reading docs yourself, Claude can just look things up.
Supabase MCP
1claude mcp add supabase --url "https://mcp.supabase.com/mcp?project_ref=YOUR_PROJECT_REF"It opens a browser for auth. No tokens to manage.
Mastra Docs MCP
1claude mcp add mastra-docs -- npx -y @mastra/mcp-docs-server@latestNow Claude has Mastra's entire documentation available in every session.
For Cursor / VS Code
Create .cursor/mcp.json (or .mcp.json) in your project root:
1{
2 "mcpServers": {
3 "supabase": {
4 "type": "url",
5 "url": "https://mcp.supabase.com/mcp?project_ref=YOUR_PROJECT_REF"
6 },
7 "mastra": {
8 "command": "npx",
9 "args": ["-y", "@mastra/mcp-docs-server@latest"]
10 }
11 }
12}⚠️ Only use the Supabase MCP with dev projects. Never connect it to production data.
Step 7 → Write Your CLAUDE.md
This is the single biggest productivity lever. Claude reads this file at the start of every session.
Run /init inside Claude Code to generate a starter, then trim it down to what matters. Here's a template:
1# Orangutan Kit
2Next.js 15 app with Supabase, Resend email, and Mastra AI agents.
3
4## Commands
5- `npm run dev` — dev server (port 3000)
6- `npm run build` — production build
7- `npm run lint` — ESLint
8- `npx mastra dev` — Mastra playground (port 4111)
9
10## Architecture
11- /src/app — Pages, layouts, API routes
12- /src/components — Reusable React components
13- /src/lib/supabase — Supabase client utilities
14- /src/mastra — AI agents, tools, workflows
15
16## Code Style
17- TypeScript strict, no `any`
18- ES module imports
19- Tailwind only, no custom CSS files
20- Server Components by default
21
22## Rules
23- NEVER commit .env.local
24- Agent definitions go in /src/mastra/agents/
25- Use @supabase/ssr for server-side clientsKeep it under 200 lines. If it's longer, Claude starts ignoring rules uniformly. Put domain-specific knowledge in .claude/skills/ instead.
Quick Reference Links
| Tool | Docs |
|---|---|
| Next.js | nextjs.org/docs |
| Supabase | supabase.com/docs |
| Convex | docs.convex.dev |
| Resend | resend.com/docs |
| Mastra | mastra.ai/docs |
| Claude Code | code.claude.com/docs |
| Supabase MCP | supabase.com/docs/guides/getting-started/mcp |
| Mastra MCP | mastra.ai/docs/build-with-ai/mcp-docs-server |
📋 COPY-PASTE SECTION: Feed This to an AI Agent
Everything below is a self-contained prompt. Copy the entire block and paste it into Claude Code, Cursor, or any AI coding agent to have it set up the Orangutan Kit for you.
1You are setting up a project called "The Orangutan Kit" — a full-stack TypeScript development toolkit. Follow these steps exactly. Ask me to choose between Supabase or Convex before starting Step 2.
2
3## STEP 1: SCAFFOLD NEXT.JS
4
5Run:
6 npx create-next-app@latest orangutan-app --yes
7 cd orangutan-app
8
9This creates a Next.js 15 app with TypeScript, Tailwind CSS, ESLint, App Router, and Turbopack.
10
11Create these folders if they don't exist:
12 src/lib/
13 src/components/
14 src/mastra/agents/
15
16## STEP 2A: IF SUPABASE — Install Database
17
18Run:
19 npm install @supabase/supabase-js @supabase/ssr
20
21Create file src/lib/supabase/client.ts:
22 import { createBrowserClient } from "@supabase/ssr";
23 export function createClient() {
24 return createBrowserClient(
25 process.env.NEXT_PUBLIC_SUPABASE_URL!,
26 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
27 );
28 }
29
30Create file src/lib/supabase/server.ts:
31 import { createServerClient } from "@supabase/ssr";
32 import { cookies } from "next/headers";
33 export async function createClient() {
34 const cookieStore = await cookies();
35 return createServerClient(
36 process.env.NEXT_PUBLIC_SUPABASE_URL!,
37 process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
38 { cookies: { getAll() { return cookieStore.getAll(); }, setAll(cookiesToSet) { cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options)); } } }
39 );
40 }
41
42Add to .env.local:
43 NEXT_PUBLIC_SUPABASE_URL=PLACEHOLDER
44 NEXT_PUBLIC_SUPABASE_ANON_KEY=PLACEHOLDER
45
46Tell me to fill in the real values from my Supabase dashboard.
47
48## STEP 2B: IF CONVEX — Install Database
49
50Run:
51 npm install convex
52
53Create file src/app/ConvexClientProvider.tsx:
54 "use client";
55 import { ConvexProvider, ConvexReactClient } from "convex/react";
56 const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
57 export default function ConvexClientProvider({ children }: { children: React.ReactNode }) {
58 return <ConvexProvider client={convex}>{children}</ConvexProvider>;
59 }
60
61Wrap the children in src/app/layout.tsx with <ConvexClientProvider>.
62
63Tell me to run `npx convex dev` in a separate terminal to initialize the backend.
64
65## STEP 3: INSTALL EMAIL (RESEND)
66
67Run:
68 npm install resend @react-email/components
69
70Create file src/components/email-template.tsx:
71 import * as React from "react";
72 export function WelcomeEmail({ name }: { name: string }) {
73 return (<div><h1>Welcome, {name}!</h1><p>Thanks for joining the Orangutan Kit.</p></div>);
74 }
75
76Create file src/app/api/send/route.ts:
77 import { Resend } from "resend";
78 import { WelcomeEmail } from "@/components/email-template";
79 const resend = new Resend(process.env.RESEND_API_KEY);
80 export async function POST() {
81 const { data, error } = await resend.emails.send({
82 from: "Orangutan Kit <onboarding@resend.dev>",
83 to: ["delivered@resend.dev"],
84 subject: "Welcome!",
85 react: WelcomeEmail({ name: "Friend" }),
86 });
87 if (error) return Response.json({ error }, { status: 500 });
88 return Response.json(data);
89 }
90
91Add to .env.local:
92 RESEND_API_KEY=PLACEHOLDER
93
94Tell me to fill in my Resend API key.
95
96## STEP 4: INSTALL AI (MASTRA)
97
98Run:
99 npm install @mastra/core @ai-sdk/anthropic
100
101Create file src/mastra/agents/index.ts:
102 import { Agent } from "@mastra/core/agent";
103 import { anthropic } from "@ai-sdk/anthropic";
104 export const orangutanAgent = new Agent({
105 name: "Orangutan Assistant",
106 instructions: "You are a helpful AI assistant for the Orangutan Kit project. Help users with their code, answer questions about the stack, and suggest improvements.",
107 model: anthropic("claude-sonnet-4-20250514"),
108 });
109
110Add to .env.local:
111 ANTHROPIC_API_KEY=PLACEHOLDER
112
113## STEP 5: CONFIGURE MCP SERVERS
114
115Create file .mcp.json in the project root:
116 {
117 "mcpServers": {
118 "supabase": {
119 "type": "url",
120 "url": "https://mcp.supabase.com/mcp?project_ref=PLACEHOLDER"
121 },
122 "mastra": {
123 "command": "npx",
124 "args": ["-y", "@mastra/mcp-docs-server@latest"]
125 }
126 }
127 }
128
129If using Convex instead of Supabase, remove the supabase entry from mcpServers.
130
131Also create .cursor/mcp.json with the same content (for Cursor IDE support).
132
133Tell me to run these commands in Claude Code to register the servers:
134 claude mcp add mastra-docs -- npx -y @mastra/mcp-docs-server@latest
135 claude mcp add supabase --url "https://mcp.supabase.com/mcp?project_ref=PLACEHOLDER"
136
137## STEP 6: CREATE CLAUDE.md
138
139Create file CLAUDE.md in the project root:
140
141 # Orangutan Kit
142 Next.js 15 app with [Supabase/Convex], Resend email, and Mastra AI agents.
143
144 ## Commands
145 - `npm run dev` — Start dev server (port 3000)
146 - `npm run build` — Production build
147 - `npm run lint` — ESLint check
148 - `npx mastra dev` — Mastra playground (port 4111)
149
150 ## Architecture
151 - /src/app — Next.js App Router pages, layouts, API routes
152 - /src/components — Reusable React components
153 - /src/lib — Utilities (Supabase clients, helpers)
154 - /src/mastra — AI agents, tools, workflows
155 - /convex — Convex backend functions (if using Convex)
156
157 ## Code Style
158 - TypeScript strict mode, no `any` types
159 - ES module imports (import/export, not require)
160 - Tailwind CSS for all styling, no custom CSS files
161 - Server Components by default, add "use client" only when needed
162 - Named exports preferred over default exports
163
164 ## Important Rules
165 - NEVER commit .env.local
166 - All AI agent definitions go in /src/mastra/agents/
167 - Use @supabase/ssr for server-side Supabase clients (not @supabase/supabase-js directly)
168 - API routes go in /src/app/api/
169 - Test email routes with onboarding@resend.dev on free tier
170
171## STEP 7: VERIFY
172
173Run `npm run dev` and confirm the app loads at http://localhost:3000.
174List all files created and summarize what was set up.
175Remind me of all the PLACEHOLDER values I need to fill in.That's the whole kit. Go build something. 🦧