Technology Stack
Complete guide to every technology used in Izri and why we chose it
๐ Stack at a Glance
| Category | Technology | Version | Purpose |
|---|---|---|---|
| Frontend Framework | React Router | v7 | Modern React framework with SSR |
| UI Library | React | v19 | User interface components |
| Styling | Tailwind CSS | v3 | Utility-first CSS framework |
| Component Library | shadcn/ui | Latest | Accessible UI components |
| Build Tool | Vite | v6 | Fast build and dev server |
| Backend Framework | Hono | v4 | Lightweight web framework |
| API Layer | tRPC | v11 | Type-safe RPC framework |
| ORM | Drizzle ORM | Latest | TypeScript-first ORM |
| Database | PostgreSQL | 15 | Relational database |
| Cache | Redis | 7 | In-memory data store |
| AI Backend | FastAPI | Latest | Python async framework |
| Runtime | Node.js | 18+ | JavaScript runtime |
| Package Manager | pnpm | 10+ | Fast, disk-efficient PM |
| Monorepo Tool | Turbo | v2 | Build system orchestrator |
| Language | TypeScript | 5.3+ | Static type checking |
๐จ Frontend Technologies
React Router v7
What it is: Modern full-stack React framework with file-based routing
Why we chose it:
- โ Server-side rendering ready
- โ File-based routing with excellent DX
- โ Built-in data loading patterns
- โ Better bundle optimization than competitors
- โ Active development and community
- โ Smooth migration path from React Router v6
Alternatives considered:
- Next.js: Too opinionated, vendor lock-in concerns
- Remix: React Router v7 is the evolution of Remix
- Create React App: No SSR, deprecated
Key Features:
// Type-safe route definitions
import { type Route } from "./+types/projects"
export async function loader({ params }: Route.LoaderArgs) {
return { project: await getProject(params.id) }
}
export default function Project({ loaderData }: Route.ComponentProps) {
return <div>{loaderData.project.name}</div>
}
React 19
What it is: Latest version of the React library
Why we use it:
- โ Improved concurrent features
- โ Better server components support
- โ Enhanced performance
- โ New compiler optimizations
Tailwind CSS
What it is: Utility-first CSS framework
Why we chose it:
- โ Rapid UI development
- โ Consistent design system
- โ Small production bundle (purged)
- โ No CSS naming conflicts
- โ Excellent IntelliSense support
Configuration:
// tailwind.config.js
export default {
content: ['./app/**/*.{js,jsx,ts,tsx}'],
theme: {
extend: {
colors: {
// Custom brand colors
}
}
}
}
shadcn/ui
What it is: Copy-paste component library built on Radix UI
Why we chose it:
- โ Accessible by default (Radix UI)
- โ Fully customizable (you own the code)
- โ Consistent with Tailwind
- โ No runtime dependency bloat
- โ TypeScript support
Components used:
- Button, Input, Select, Dialog
- Table, Card, Badge, Avatar
- DropdownMenu, Tooltip, Toast
- Form components with validation
Vite
What it is: Next-generation frontend build tool
Why we use it:
- โ Lightning-fast HMR (<100ms)
- โ ESM-based dev server
- โ Optimized production builds
- โ Built-in TypeScript support
- โ Rich plugin ecosystem
โ๏ธ Backend Technologies
Hono
What it is: Ultra-fast web framework for edge and Node.js
Why we chose it:
- โ Fastest Node.js framework (benchmarks)
- โ Express-like API (familiar)
- โ Excellent TypeScript support
- โ Built-in middleware ecosystem
- โ Edge runtime compatible
- โ Tiny bundle size (~10KB)
Alternatives considered:
- Express: Slower, older architecture
- Fastify: Good but more complex
- Koa: Less active community
Example:
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
const app = new Hono()
app.use('*', logger())
app.use('*', cors())
app.get('/health', (c) => c.json({ status: 'ok' }))
tRPC
What it is: End-to-end type-safe RPC framework
Why we chose it:
- โ No code generation needed
- โ Full type safety from DB to UI
- โ Excellent DX with autocomplete
- โ Automatic request/response validation
- โ Built-in error handling
- โ WebSocket support
Alternatives considered:
- REST: No type safety, boilerplate
- GraphQL: Code generation, complexity
- gRPC: Protocol buffers, overkill
Architecture:
// Backend: Define procedures
export const projectRouter = router({
list: publicProcedure.query(async ({ ctx }) => {
return ctx.db.select().from(projects)
}),
create: protectedProcedure
.input(createProjectSchema)
.mutation(async ({ ctx, input }) => {
return ctx.db.insert(projects).values(input)
})
})
// Frontend: Type-safe calls
const projects = await trpc.projects.list.query()
await trpc.projects.create.mutate({ name: 'New Project' })
Drizzle ORM
What it is: TypeScript ORM that feels like writing SQL
Why we chose it:
- โ SQL-like syntax (familiar)
- โ Zero runtime overhead
- โ Full TypeScript inference
- โ No magic, no proxies
- โ Excellent migration system
- โ Drizzle Studio for visualization
Alternatives considered:
- Prisma: Runtime overhead, code generation
- TypeORM: Complex, heavy
- Kysely: Great but less ecosystem
Example:
// Define schema
import { ulid } from 'ulid';
export const projects = pgTable('projects', {
id: varchar('id', { length: 191 }).primaryKey(), // ULID stored as varchar
name: text('name').notNull(),
organizationId: varchar('organization_id', { length: 191 }).references(() => organizations.id),
createdAt: timestamp('created_at').defaultNow()
})
// Query with type safety
const result = await db
.select()
.from(projects)
.where(eq(projects.organizationId, orgId))
.leftJoin(testRuns, eq(testRuns.projectId, projects.id))
// When inserting, generate ULID
const projectId = ulid();
await db.insert(projects).values({
id: projectId,
name: 'My Project',
// ...
})
๐พ Data Storage
PostgreSQL 15
What it is: Advanced open-source relational database
Why we chose it:
- โ ACID transactions
- โ JSONB support (flexible schemas)
- โ Excellent indexing options
- โ Rich extension ecosystem
- โ Proven at scale
- โ Strong community support
Features we use:
- JSONB columns for flexible data
- Full-text search
- Partial indexes
- Foreign key constraints
- Transactions
Configuration:
# docker-compose.yml
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: izri
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- "5433:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
Redis 7
What it is: In-memory data structure store
Why we use it:
- โ Ultra-fast caching (<1ms reads)
- โ Session storage
- โ Rate limiting support
- โ Pub/sub messaging
- โ Simple to operate
Use cases:
- Session management (Lucia)
- API response caching
- Rate limiting (planned)
- Background job queues (planned)
๐ค AI & Analysis
Python 3.12
Why Python for AI:
- โ Best ecosystem for ML/AI
- โ LangChain and AI frameworks
- โ Tree-sitter for code parsing
- โ Excellent async support
FastAPI
What it is: Modern Python web framework
Why we chose it:
- โ Async/await support
- โ Automatic API documentation
- โ Type hints with Pydantic
- โ Fast performance
- โ Easy to test
Example:
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class AnalysisRequest(BaseModel):
repo_url: str
branch: str = "main"
@app.post("/analyze")
async def analyze_repo(request: AnalysisRequest):
# Perform analysis
return {"status": "success"}
๐ ๏ธ Development Tools
pnpm
What it is: Fast, disk space efficient package manager
Why we chose it:
- โ 3x faster than npm
- โ Efficient disk usage (symlinks)
- โ Strict dependency resolution
- โ Built-in monorepo support
- โ Workspace protocol
Workspace structure:
# pnpm-workspace.yaml
packages:
- 'apps/*'
- 'packages/*'
Turbo
What it is: High-performance build system for monorepos
Why we chose it:
- โ Intelligent caching
- โ Parallel execution
- โ Remote caching support
- โ Task pipelines
- โ Simple configuration
Configuration:
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**", "lib/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
TypeScript 5.3+
Why TypeScript:
- โ Static type checking
- โ Better IDE support
- โ Catch errors at compile time
- โ Self-documenting code
- โ Refactoring confidence
Configuration highlights:
{
"compilerOptions": {
"strict": true,
"noUncheckedIndexedAccess": true,
"moduleResolution": "bundler",
"verbatimModuleSyntax": true
}
}
๐งช Testing & Quality
Biome
What it is: Fast formatter and linter (Rust-based)
Why we use it:
- โ 10x faster than ESLint+Prettier
- โ Single tool for format + lint
- โ Drop-in replacement
- โ Minimal configuration
ESLint (Legacy)
Current state: Transitioning to Biome
Still used for:
- React-specific linting
- Import order enforcement
๐ณ Infrastructure & DevOps
Docker & Docker Compose
Why we use it:
- โ Consistent development environment
- โ Easy service orchestration
- โ Production parity
- โ Simplified onboarding
Services:
services:
postgres:
image: postgres:15-alpine
redis:
image: redis:7-alpine
api:
build: ./docker/api
web:
build: ./docker/web
๐ Comparison with Alternatives
Why Not Next.js?
| Feature | React Router v7 | Next.js |
|---|---|---|
| SSR | โ Yes | โ Yes |
| File Routing | โ Flexible | โ Pages/App dir |
| Vendor Lock-in | โ None | โ Vercel-optimized |
| Edge Functions | โ Yes | โ Yes |
| Learning Curve | โ Lower | โ ๏ธ Higher |
| Bundle Size | โ Smaller | โ ๏ธ Larger |
Why tRPC Over GraphQL?
| Feature | tRPC | GraphQL |
|---|---|---|
| Type Safety | โ Native TS | โ ๏ธ Code generation |
| Setup Complexity | โ Minimal | โ High |
| Learning Curve | โ Easy | โ Steep |
| Over-fetching | โ ๏ธ Can happen | โ Prevented |
| Tooling | โ Great | โ Excellent |
| Ecosystem | โ Growing | โ Mature |
Why Drizzle Over Prisma?
| Feature | Drizzle | Prisma |
|---|---|---|
| Runtime Overhead | โ Zero | โ 4MB+ |
| SQL-like API | โ Yes | โ DSL |
| Type Inference | โ Native | โ ๏ธ Generated |
| Migrations | โ SQL files | โ Own format |
| Studio | โ Yes | โ Yes |
| Edge Compatible | โ Yes | โ No |
๐ Learning Resources
Official Documentation
Internal Guides
๐ Keeping Up to Date
Monitoring Updates
# Check for outdated packages
pnpm outdated
# Update all to latest within version ranges
pnpm update
# Update specific package
pnpm update react-router
Upgrade Strategy
- Patch versions: Auto-update (security fixes)
- Minor versions: Review changelog, test, update
- Major versions: Plan migration, test extensively, update docs
๐ Next Steps
- Monorepo Structure: Understand code organization
- Design Decisions: Learn why these choices were made
- Frontend Docs: Deep dive into React Router app
- Backend Docs: Deep dive into Hono + tRPC API
Questions about a specific technology? Check the official docs linked above or ask the team.