Tech Stack
Tech Stack
Solo Kit is built with a carefully curated selection of modern, production-ready technologies. Each choice prioritizes developer experience, performance, and maintainability.
ποΈ Architecture Overview
Solo Kit follows a monorepo architecture with shared packages and separate applications:
solo-kit/
βββ apps/
β βββ web/ # Next.js web application
β βββ mobile/ # Expo mobile application
βββ packages/
β βββ ui/ # Shared UI components
β βββ utils/ # Shared utilities
β βββ database/ # Database layer
β βββ eslint-config/# Shared ESLint rules
π Frontend Technologies
Next.js 15
The React framework for production
- App Router - Modern routing with layouts and nested routes
- Server Components - Render components on the server for better performance
- Server Actions - Type-safe server mutations
- Image Optimization - Automatic image optimization and WebP conversion
- Bundle Analyzer - Built-in bundle analysis tools
// Example Server Component
export default async function HomePage() {
const data = await getData(); // Runs on server
return <Dashboard data={data} />;
}
React 18
The library for web and native user interfaces
- Concurrent Features - Better user experience with concurrent rendering
- Suspense - Declarative loading states
- Server Components - React components that run on the server
- Streaming - Progressive page rendering
TypeScript
JavaScript with syntax for types
- Full Type Safety - From database to UI components
- IntelliSense - Better developer experience with autocomplete
- Refactoring - Safe code refactoring across the entire codebase
- Build-time Error Catching - Catch errors before they reach production
// Type-safe API response
interface User {
id: string;
name: string;
email: string;
createdAt: Date;
}
// Type-safe database query
const users: User[] = await db.select().from(usersTable);
π¨ Styling & UI
Tailwind CSS
A utility-first CSS framework
- Utility Classes - Compose styles with utility classes
- Responsive Design - Mobile-first responsive design
- Dark Mode - Built-in dark mode support
- Custom Design System - Consistent spacing, colors, and typography
- JIT Mode - Just-in-time compilation for faster builds
<div className="bg-white dark:bg-gray-900 rounded-lg shadow-md p-6">
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
Welcome to Solo Kit
</h1>
</div>
shadcn/ui
Beautifully designed components built with Radix UI and Tailwind CSS
- Accessible - Built with accessibility in mind
- Customizable - Easy to customize and theme
- Copy & Paste - Copy components directly into your project
- Type Safe - Full TypeScript support
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
<Card>
<CardHeader>
<CardTitle>Dashboard</CardTitle>
</CardHeader>
<CardContent>
<Button variant="outline">Get Started</Button>
</CardContent>
</Card>
Radix UI
Low-level UI primitives with accessibility built-in
- Headless Components - Unstyled, accessible components
- Keyboard Navigation - Full keyboard support
- Screen Reader Support - Proper ARIA attributes
- Focus Management - Proper focus management
π± Mobile Development
Expo
An open-source platform for making universal native apps
- Managed Workflow - Simplified development and deployment
- Over-the-Air Updates - Update your app without app store approval
- Native APIs - Access to device features like camera, location, notifications
- Cross-Platform - Single codebase for iOS and Android
// Shared component between web and mobile
import { Button } from '@packages/ui';
export function WelcomeScreen() {
return (
<View style={styles.container}>
<Text>Welcome to Solo Kit Mobile!</Text>
<Button onPress={() => navigation.navigate('Dashboard')}>
Get Started
</Button>
</View>
);
}
React Native
Create native apps using React
- Native Performance - True native app performance
- Hot Reloading - Fast development feedback loop
- Platform APIs - Access to platform-specific APIs
- Code Sharing - Share logic and components with web
ποΈ Database & Backend
PostgreSQL
The world's most advanced open source relational database
- ACID Compliance - Reliable transactions
- JSON Support - Native JSON and JSONB data types
- Full-Text Search - Built-in search capabilities
- Scalability - Scales from prototype to enterprise
- Extensions - Rich ecosystem of extensions
-- Example PostgreSQL features
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
profile JSONB NOT NULL,
search_vector TSVECTOR GENERATED ALWAYS AS (
to_tsvector('english', name || ' ' || email)
) STORED
);
CREATE INDEX idx_users_search ON users USING GIN (search_vector);
Drizzle ORM
TypeScript ORM for SQL databases
- Type Safety - Full type safety from schema to queries
- SQL-like Syntax - Write SQL-like queries in TypeScript
- Zero Runtime Overhead - No runtime schema validation
- Migration System - Automatic migration generation
- Multi-Database - Support for PostgreSQL, MySQL, SQLite
// Define schema
export const usersTable = pgTable('users', {
id: uuid('id').primaryKey().defaultRandom(),
name: text('name').notNull(),
email: text('email').notNull().unique(),
createdAt: timestamp('created_at').defaultNow().notNull(),
});
// Type-safe queries
const users = await db
.select()
.from(usersTable)
.where(eq(usersTable.email, 'user@example.com'));
Drizzle Studio
Visual database explorer and editor
- Visual Schema - Visual representation of your database
- Data Explorer - Browse and edit data visually
- Query Builder - Visual query builder
- Real-time Updates - See changes in real-time
π Authentication
BetterAuth
The most comprehensive authentication library for TypeScript
- Session-based - Secure session management with cookie caching
- Multiple Providers - OAuth, email/password, magic links
- Type Safe - Full TypeScript support
- Plugins - Extensive plugin ecosystem
- Security - Built-in CSRF protection and rate limiting
import { betterAuth } from "better-auth";
export const auth = betterAuth({
database: {
provider: "pg",
url: process.env.DATABASE_URL,
},
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
},
},
});
π§ Email System
React Email
Build and send emails using React and TypeScript
- React Components - Build emails using familiar React syntax
- TypeScript Support - Full type safety in email templates
- Preview Mode - Preview emails in development
- Responsive - Mobile-responsive email templates
import { Button, Html, Head, Body } from '@react-email/components';
export function WelcomeEmail({ name }: { name: string }) {
return (
<Html>
<Head />
<Body>
<h1>Welcome to Solo Kit, {name}!</h1>
<Button href="https://example.com/dashboard">
Get Started
</Button>
</Body>
</Html>
);
}
Email Providers
Multiple email service providers supported
- Resend - Modern email API for developers (recommended)
- SendGrid - Reliable email delivery platform
- Postmark - Fast, reliable transactional email
- Console Logging - Development mode fallback
π³ Payment Processing
Stripe
Online payment processing for internet businesses
- Comprehensive APIs - Complete payment solution
- Strong Customer Authentication - SCA compliance built-in
- Subscriptions - Recurring payment management
- Webhooks - Real-time payment notifications
- Test Mode - Full testing environment
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
// Create payment intent
const paymentIntent = await stripe.paymentIntents.create({
amount: 2000,
currency: 'usd',
metadata: { userId: 'user_123' },
});
Alternative Payment Providers
Multiple payment providers supported
- PayMongo - Payment gateway for Southeast Asia
- Lemon Squeezy - All-in-one platform for digital products
- Polar - Payment processing for developers
π Internationalization
next-intl
Internationalization for Next.js applications
- Type Safe - Type-safe translations with TypeScript
- Server Components - Works with React Server Components
- Locale Routing - Automatic locale detection and routing
- Rich Formatting - Date, time, number, and message formatting
// messages/en.json
{
"welcome": "Welcome to Solo Kit",
"userGreeting": "Hello {name}, you have {count, plural, =0 {no messages} =1 {one message} other {# messages}}"
}
// Component usage
import { useTranslations } from 'next-intl';
export function Welcome({ name, messageCount }) {
const t = useTranslations();
return (
<div>
<h1>{t('welcome')}</h1>
<p>{t('userGreeting', { name, count: messageCount })}</p>
</div>
);
}
π§ͺ Testing
Vitest
A blazing fast unit test framework powered by Vite
- Fast Execution - Powered by Vite for fast test runs
- Jest Compatible - Drop-in replacement for Jest
- TypeScript Support - Native TypeScript support
- Watch Mode - Interactive watch mode
- Code Coverage - Built-in code coverage
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { Button } from '@/components/ui/button';
describe('Button', () => {
it('renders button text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
});
Playwright
Fast and reliable end-to-end testing
- Cross Browser - Test on Chrome, Firefox, Safari
- Auto-wait - Automatic waiting for elements
- Screenshots - Visual testing capabilities
- Mobile Testing - Test mobile viewports
- Parallel Execution - Fast test execution
import { test, expect } from '@playwright/test';
test('user can sign up', async ({ page }) => {
await page.goto('/signup');
await page.fill('[data-testid="email"]', 'test@example.com');
await page.fill('[data-testid="password"]', 'password123');
await page.click('[data-testid="submit"]');
await expect(page).toHaveURL('/dashboard');
});
π§ Development Tools
pnpm
Fast, disk space efficient package manager
- Fast Installs - Up to 2x faster than npm
- Disk Efficient - Saves gigabytes of disk space
- Monorepo Support - Great support for monorepos
- Strict - Prevents access to unlisted dependencies
ESLint + Prettier
Code quality and formatting
- Code Quality - Catch bugs and enforce best practices
- Consistent Formatting - Automatic code formatting
- Custom Rules - Project-specific linting rules
- IDE Integration - Works with all major editors
Turbo
High-performance build system for JavaScript and TypeScript codebases
- Fast Builds - Incremental builds and smart caching
- Parallel Execution - Run tasks in parallel
- Remote Caching - Share cache across team members
- Task Scheduling - Intelligent task dependency resolution
π Deployment & Infrastructure
Vercel
The platform for frontend developers
- Zero Config - Deploy with zero configuration
- Edge Network - Global edge network for fast loading
- Preview Deployments - Deploy every git push
- Serverless Functions - Auto-scaling serverless functions
- Analytics - Built-in performance analytics
Docker
Containerization platform
- Consistent Environment - Same environment everywhere
- Easy Deployment - Deploy anywhere Docker runs
- Multi-stage Builds - Optimized production images
- Health Checks - Built-in health checking
# Multi-stage Docker build
FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM base AS dev
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]
π Monitoring & Analytics
Sentry
Error tracking and performance monitoring
- Error Tracking - Automatic error capture and alerting
- Performance Monitoring - Track application performance
- User Context - Link errors to specific users
- Source Maps - Readable stack traces in production
import * as Sentry from "@sentry/nextjs";
Sentry.init({
dsn: process.env.SENTRY_DSN,
tracesSampleRate: 1.0,
environment: process.env.NODE_ENV,
});
π State Management
React Query (TanStack Query)
Data fetching and caching library
- Automatic Caching - Intelligent caching and background updates
- Optimistic Updates - Instant UI updates
- DevTools - Powerful development tools
- Offline Support - Work offline with cached data
import { useQuery } from '@tanstack/react-query';
function UserProfile({ userId }: { userId: string }) {
const { data: user, isLoading, error } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <div>Welcome {user.name}!</div>;
}
Zustand
Small, fast, and scalable state management
- Minimal Boilerplate - Simple API with no reducers
- TypeScript Support - Full TypeScript integration
- DevTools - Redux DevTools integration
- No Providers - No need to wrap components
import { create } from 'zustand';
interface ThemeState {
theme: 'light' | 'dark';
toggleTheme: () => void;
}
export const useTheme = create<ThemeState>((set) => ({
theme: 'light',
toggleTheme: () => set((state) => ({
theme: state.theme === 'light' ? 'dark' : 'light'
})),
}));
πββοΈ Performance Optimization
Next.js Optimization Features
- Automatic Code Splitting - Split code automatically by pages and components
- Image Optimization - Automatic image optimization and modern formats
- Bundle Analyzer - Analyze and optimize bundle sizes
- Static Generation - Pre-render pages at build time
- Incremental Static Regeneration - Update static content after build
Caching Strategies
- React Query - Automatic server state caching
- Next.js Cache - Static and dynamic content caching
- CDN Caching - Global content delivery network
- Browser Caching - Leverage browser caching for static assets
This comprehensive tech stack provides a solid foundation for building modern, scalable SaaS applications while maintaining excellent developer experience and performance.
Next Steps
Now that you understand the tech stack, explore these sections:
- Getting Started - Set up your development environment
- Architecture - Understanding the system design
- Database - Learn about the PostgreSQL integration
- Authentication - Implement secure authentication