A production-ready starter kit for building full-stack dApps with Next.js 15, Porto web3 accounts, and Better Auth. Perfect for hackathons and MVPs that need passwordless authentication with wallet-based sign-in.
- Passwordless Authentication - Sign in with Ethereum (SIWE) using Porto wallet connector
- Type-Safe API - End-to-end type safety with tRPC v11
- Database Ready - Drizzle ORM with Neon Postgres (serverless)
- Modern Stack - Next.js 15 with App Router, React 19, and TailwindCSS v4
- Web3 Native - Support for Base and Base Sepolia chains out of the box
- Developer Experience - Hot reload with Turbopack, TypeScript everywhere
- Next.js 15.4 - React framework with App Router
- React 19 - UI library
- TailwindCSS v4 - Utility-first CSS
- Wagmi v2 - React hooks for Ethereum
- Porto - Passwordless web3 accounts
- Radix UI - Headless UI components
- tRPC v11 - Type-safe API layer
- Better Auth - Authentication library with SIWE support
- Drizzle ORM - TypeScript ORM
- Neon - Serverless Postgres
- Clone and install dependencies
git clone https://github.com/your-repo/unite-defi-starter.git
cd unite-defi-starter
bun install
- Set up environment variables
Copy .env.example
to .env
and configure:
# Database (get your connection string from neon.tech)
DATABASE_URL="postgresql://..."
# Better Auth
BETTER_AUTH_SECRET="your-secret-here"
BETTER_AUTH_URL="http://localhost:3000"
# App URL
NEXT_PUBLIC_APP_URL="http://localhost:3000"
- Set up the database
# Generate database migrations
bun db:generate
# Run migrations
bun db:migrate
# (Optional) Open Drizzle Studio to view your database
bun db:studio
- Start the development server
bun dev
Open https://localhost:3000 - the app runs with HTTPS in development for secure wallet connections.
src/
├── app/ # Next.js App Router
│ ├── api/ # API routes
│ │ └── trpc/ # tRPC endpoint
│ ├── dashboard/ # Protected dashboard page
│ └── page.tsx # Home page
├── components/ # React components
│ ├── ui/ # Base UI components (shadcn/ui)
│ └── features/ # Feature components
│ └── PortoConnect.tsx # Wallet connection component
├── config/ # Configuration files
│ └── wagmiConfig.ts # Wagmi configuration
├── env/ # Environment validation
│ ├── clientEnv.ts # Client-side env vars
│ └── serverEnv.ts # Server-side env vars
├── hooks/ # Custom React hooks
│ └── useSession.ts # Session management hook
├── lib/ # Utilities and helpers
│ ├── auth.ts # Better Auth configuration
│ ├── auth-client.ts # Auth client helpers
│ └── utils.ts # General utilities
└── server/ # Server-side code
├── db/ # Database
│ ├── schema.db.ts # Drizzle schema
│ └── drizzle.ts # Database client
└── trpc/ # tRPC setup
└── routers/ # API routers
- User connects their Porto wallet
- App requests a nonce from the server
- User signs a SIWE message with their wallet
- Server verifies the signature using Porto's server actions
- Session is created and stored in the database
- User is redirected to the dashboard
The tRPC router provides these endpoints:
hello
- Public endpoint for testingprofile
- Get authenticated user's profilewalletAddresses
- List connected wallet addressesuserStats
- Get user statisticsupdateProfile
- Update user profile information
This starter includes a set of reusable UI components from shadcn/ui:
Button
- Styled button component with variantsDropdownMenu
- Accessible dropdown menus- Additional components can be added with the shadcn CLI
# Development
bun dev # Start dev server with HTTPS & Turbopack
# Database
bun db:generate # Generate migrations from schema changes
bun db:migrate # Apply pending migrations
bun db:studio # Open Drizzle Studio GUI
# Build & Deploy
bun build # Build for production
bun start # Start production server
# Code Quality
bun lint # Run ESLint
bun format # Format with Prettier
- Push your code to GitHub
- Connect your repo to Vercel
- Add environment variables in Vercel dashboard
- Deploy!
This starter is optimized for serverless deployment but can run anywhere Node.js is supported:
- Railway
- Render
- Fly.io
- AWS Amplify
- Netlify
Variable | Description | Required |
---|---|---|
DATABASE_URL |
PostgreSQL connection string | ✅ |
BETTER_AUTH_SECRET |
Secret for signing sessions | ✅ |
BETTER_AUTH_URL |
Your app's URL | ✅ |
NEXT_PUBLIC_APP_URL |
Public app URL | ✅ |
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Porto Documentation - Learn about Porto wallets
- Better Auth Docs - Authentication library docs
- tRPC Documentation - Type-safe API development
- Drizzle ORM Docs - Database ORM documentation
- Wagmi Documentation - Ethereum React hooks
MIT License - do whatever you want with this code!
Built with 💜 for the Unite DeFi Hackathon 2025