A modern, batteries-included Next.js template designed to get you into the flow quickly. Skip the setup and start building.
Ivan (a play on Aiven) is a self-hostable, Lovable-style shell: describe a change in plain English and Ivan edits a locked template repo on a fresh branch inside a Vercel Sandbox, you watch the result live in an iframe, then ship a PR. Live sandbox handles run in-process, while DATABASE_URL gives Ivan durable session, log, message, attachment, and Slack thread state across redeploys and cold starts.
src/lib/shell/— the engine: provision a sandbox, clone the target repo, install deps + the Claude Code CLI, startnext devon an exposed port, run the agent (stream-json), commit/push, open the PR.src/lib/shell/claude-skills/— Ivan-owned Claude Code skills copied into the sandbox as~/.claude/skills/*before each agent run.src/lib/shell/store.ts— runtime session handles + a per-session SSE event bus, backed by Postgres snapshots whenDATABASE_URLis set.src/lib/shell/persistence.ts— Postgres tables for sessions, logs, messages, image attachments, Claude resume ids, and Slack thread ids.src/app/api/sessions/**— create / list / event-stream / message / resume / submit.src/app/page.tsx+src/app/workspace/[id]— launcher and the chat-plus-live-preview workspace.
The agent runs inside the sandbox (the same model as a local coding agent), so its editing secrets live in the sandbox. Production deployments should set DATABASE_URL so Ivan can restore workspace links after Vercel redeploys or instance swaps.
- Copy
.env.exampleto.envand fill it in (Anthropic key, target repo, GitHub token, Vercel Sandbox credentials, andDATABASE_URLfor durable sessions). pnpm dev, open the app, describe a change, and watch the preview.
Slack messages use the same Ivan session flow as the app text box, via Chat SDK's official Slack adapter. When DATABASE_URL is set, Chat SDK also stores Slack subscriptions, locks, and webhook dedupe in Postgres so Slack retries do not create duplicate sessions.
- Set
SLACK_BOT_TOKENandSLACK_SIGNING_SECRET. SetIVAN_APP_URLto your deployed app URL if you want Slack replies to link to the workspace. - In Slack, set the Events API request URL to
https://your-domain.com/api/webhooks/slack. - Add bot scopes for the surfaces you want:
chat:write,app_mentions:read,channels:history,channels:read,groups:history,groups:read,im:history,im:read,mpim:history, andmpim:read. - Subscribe to
app_mention,message.channels,message.groups,message.im, andmessage.mpim.
Mention Ivan in a Slack thread or DM it directly. The first message creates an Ivan workspace session; later Slack messages in that same thread are sent to the same session.
Next.js 16 defaults to Turbopack, whose HMR can be unreliable behind the sandbox proxy, so src/lib/shell/creation.ts starts sandboxed dev servers with --webpack. Ivan's own dev server allowlists hosts from IVAN_APP_URL, NEXT_PUBLIC_APP_URL, and IVAN_ALLOWED_DEV_ORIGINS so it can run behind ngrok or another tunnel.
Before booting a Next 16 target app, Ivan also adds the sandbox preview host to that app's allowedDevOrigins so /_next dev resources can load from the public sb-*.vercel.run iframe, and injects devIndicators: false so the preview iframe does not show Next's development indicator.
Those runtime preview config edits are marked assume-unchanged inside the sandbox clone, then removed and unhidden before Ivan commits the agent's generated PR.
Ivan creates named persistent Vercel Sandboxes for new sessions. If a sandbox or serverless process stops, the workspace restores the session from Postgres, reattaches by sandbox name, and restarts the dev server.
This template comes pre-configured with everything you need for modern Next.js development:
- Next.js 16 with App Router and Turbopack
- React 19 with Server Components by default
- React Compiler for automatic memoization
- TypeScript with strict mode
- pnpm as the package manager
- Tailwind CSS v4 for styling
- shadcn/ui component system with reusable design-system components
- ESLint with Next.js and React-specific rules
- Prettier for consistent code formatting
- Husky + lint-staged for pre-commit hooks
- Path aliases configured (
@/imports) - Styleguide route at
/styleguide
- MCP servers pre-configured:
- shadcn component integration
- CoLoop.ai documentation access
- AI Agents optimized with custom instructions
# Install dependencies
pnpm install
# Start development server
pnpm dev
# Build for production
pnpm build
# Start production server
pnpm startThis template includes a reusable design system in src/components/ui, layout primitives in src/components/layout, and tokens in src/app/globals.css.
Open /styleguide to inspect the tokens and components.
Add more shadcn/ui components as needed:
# Add individual components
pnpm dlx shadcn@latest add button card dialog
# Or use the MCP tools in Claude Code/OpenAI Codex
# Search for components, view examples, and add them interactivelyExample usage:
import { Button } from '@/components/ui/button'
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'
export function MyComponent() {
return (
<Card>
<CardHeader>
<CardTitle>Hello World</CardTitle>
</CardHeader>
<CardContent>
<Button>Click me</Button>
</CardContent>
</Card>
)
}next-vibe-template/
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout
│ │ ├── page.tsx # Home page
│ │ ├── styleguide/ # Design-system verification page
│ │ ├── globals.css # Global styles + Tailwind theme
│ │ ├── loading.tsx # Root loading state
│ │ ├── error.tsx # Root error boundary
│ │ └── not-found.tsx # 404 page
│ ├── components/
│ │ ├── layout/ # Layout primitives
│ │ └── ui/ # Design-system components
│ ├── providers/ # Theme and motion providers
│ ├── hooks/ # Custom React hooks
│ └── lib/
│ └── utils.ts # Utility functions
├── public/ # Static assets
├── AGENTS.md # Project instructions for agents
└── components.json # shadcn configuration
# Development
pnpm dev # Start dev server
pnpm build # Build for production
pnpm start # Start production server
# Code Quality
pnpm lint # Run strict ESLint
pnpm typecheck # Type checking
pnpm format # Format with Prettier
pnpm format:check # Check formattingThis template uses pnpm because it is:
- Faster for package installation
- Strict about dependency resolution
- Widely supported in Node.js projects
- Simple to use in scripts and CI
New dependency versions must wait seven days before pnpm can install them. This is configured in pnpm-workspace.yaml as a supply-chain safety delay.
Common npm commands map cleanly to pnpm:
npm install->pnpm installnpm run dev->pnpm devnpm run build->pnpm build
Browse and add components from the shadcn registry:
# List available components
pnpm dlx shadcn@latest
# Add specific components
pnpm dlx shadcn@latest add [component-name]Edit the CSS variables in src/app/globals.css to customize your design system. The template uses Tailwind v4 with CSS-based configuration.
Use /styleguide to verify changes across light mode, dark mode, tokens, typography, and components.
This template is optimized for AI-assisted development:
- AGENTS.md: Project guidelines for AI agents
- MCP Integration: Pre-configured servers for enhanced capabilities
When using Claude Code or OpenAI Codex, the AI will automatically:
- Use pnpm for package management
- Prefer shadcn components over custom UI
- Use Server Components by default
- Follow Next.js App Router conventions
- Follow the project's code style and conventions
| Technology | Version | Purpose |
|---|---|---|
| Next.js | 16.2.9 | React meta-framework |
| React | 19.2.7 | UI framework |
| TypeScript | ~6.0.3 | Type safety |
| Tailwind CSS | 4.3.1 | Styling |
| shadcn/ui | Latest | Component library |
| pnpm | Latest | Package manager |
| ESLint | 10.5.0 | Code linting |
| Prettier | 3.8.4 | Code formatting |
MIT
Happy coding! Get in the vibe and start building.