Tech Stack
Built on proven tools
Features
Everything you need to build
Pre-built modules and features to accelerate your development process.
Authentication & Authorization
Complete auth system with session management, role-based access control, and social login.
Database & ORM
Type-safe database operations with Drizzle ORM, migrations, and PostgreSQL optimization.
API & Type Safety
End-to-end type safety with tRPC and seamless client-server communication.
File Management
Complete file handling with S3 integration, image processing, and CDN support.
Background Jobs
Robust job processing with BullMQ, scheduled tasks, and retry logic.
Email & Notifications
Multi-channel notifications with email templates and delivery tracking.
User Management
Complete user system with profiles, preferences, and activity tracking.
Monitoring & Logging
Comprehensive monitoring with Sentry, structured logging, and performance tracking.
Architecture
Scalable by design
Monorepo structure with clean separation of concerns and microservice-ready packages.
Frontend Apps
TanStack Start, React 19, SSR
API Gateway
Hono + tRPC, middleware, routing
Service Packages
Auth, database, caching, queues
Developer Experience
Type-safe from database to UI
Write backend logic once, get full autocompletion and type checking on the frontend.
import { router, authProcedure } from '@repo/trpc';
import {
getFilesByUserIdPaginated,
deleteFile,
ListFilesPaginatedSchema
} from '@repo/file';
import { IdSchema } from '@repo/server-utils';
export const fileRouter = router({
getMyFiles: authProcedure
.input(ListFilesPaginatedSchema)
.query(({ ctx, input }) => {
return getFilesByUserIdPaginated(
ctx.user.user.id, input
);
}),
deleteFile: authProcedure
.input(IdSchema)
.mutation(({ ctx, input }) => {
return deleteFile(input.id, ctx.user.user.id);
}),
});import { useTRPC } from '@/lib/trpc-client';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
export function FileList() {
const trpc = useTRPC();
const queryClient = useQueryClient();
const { data: files } = useQuery(
trpc.file.getMyFiles.queryOptions({
pagination: { page: 1, limit: 10 }
})
);
const { mutate: deleteFile } = useMutation(
trpc.file.deleteFile.mutationOptions({
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: trpc.file.pathKey()
});
}
})
);
return <div>{files?.data.length} files</div>;
}