Codapult
DocsBlogPricingPluginsDemo
Get Codapult
Logo

Build your SaaS with AI. Keep the architecture under control.

Get Codapult

Product

  • Pricing
  • Architecture
  • Modules
  • AI platform
  • Plugins

Developers

  • MCP
  • CLI
  • Documentation
  • Launch your SaaS
  • Build a B2B SaaS

Resources

  • Blog
  • FAQ

Connect

  • Contact
  • GitHub

Compare

  • SaaS template comparison
  • Codapult vs Supastarter
  • Codapult vs Makerkit
  • Codapult vs ShipFast
  • Codapult vs SaaSBold
  • Codapult vs Gravity
  • Codapult vs Nextbase
  • Codapult vs BuilderKit

Featured on

Codapult on LaunchNestCodapult on LaunchNestbetterlaunch.cobetterlaunch.coFeatured on LaunchBuffFeatured on LaunchBuffCodapult on PeerPushCodapult on PeerPushFeatured on LaunchItFeatured on LaunchIt
© 2026 Codapult·All rights reserved·Privacy Policy·Terms of Service
Full source code · One-time purchase · Self-host anywhere
All articles

Getting Started

  • Introduction
  • Quick Start
  • Your First 30 Minutes
  • Project Structure
  • License and Permitted Use
  • Starter Profiles and Recipes
  • Product Recipes

Configuration

  • Environment Variables
  • App Configuration
  • Which Modules Should I Enable?
  • Provider Matrix
  • Capability Coverage

Database

  • Database and Provider Guide
  • Database
  • Migrations

Authentication

  • Authentication
  • OAuth Providers
  • Two-Factor & Passwordless
  • Enterprise SSO (SAML)

Ai

  • AI Runtime Architecture and Evals
  • AI Features
  • Streaming Chat
  • RAG and Semantic Search
  • Quotas and Memory

Teams

  • Teams & Organizations
  • Permissions & RBAC
  • SCIM Provisioning

Security

  • Data Retention Policy
  • Security

Deployment

  • Enterprise E2E Evidence
  • Enterprise Production Readiness
  • Deployment, Backup, and Restore Runbook
  • Deployment
  • Troubleshooting

Payments

  • Payments & Billing
  • Stripe Setup
  • LemonSqueezy Setup
  • Polar Setup
  • Payment Webhooks

Api

  • API Layer
  • tRPC
  • GraphQL

Email

  • Email
  • Email Templates

Infrastructure

  • Infrastructure
  • Self-Hosting
  • File Storage
  • Docker
  • Background Jobs
  • Terraform & Pulumi
  • Kubernetes

Ui

  • UI & Theming

I18n

  • Internationalization

Content Management

  • Content Management

Admin

  • Admin Panel

Monitoring

  • Analytics & Monitoring

Modules

  • Module Architecture
  • Waitlist
  • Audit Log
  • White-Labeling
  • Workflow Automation
  • A/B Testing
  • Welcome Page
  • Referrals
  • GDPR Export and Deletion
  • Promotions
  • Outgoing Webhooks

Plugins

  • Plugin System
  • CRM Plugin
  • Helpdesk Plugin
  • Email Marketing Plugin

Upgrading

  • Upgrading Codapult

Developer Tools

  • AI Agents & IDEs
  • MCP Server
  • Testing
  • Build Your First Feature with Codapult MCP
  • How Guard Blocks an Architectural Regression
Api

tRPC

Type-safe API procedures with tRPC v11, TanStack React Query, and server-side prefetching.

Codapult includes a full tRPC v11 setup with TanStack React Query and superjson serialization. tRPC provides end-to-end type safety — your client code knows the exact shape of every request and response without code generation.

File Structure

PathDescription
src/lib/trpc/init.tsRouter factory, procedure levels (publicProcedure, protectedProcedure, adminProcedure)
src/lib/trpc/routers/Domain routers — user.ts, billing.ts, notifications.ts
src/lib/trpc/server.tsServer-side caller and prefetch() helper
src/lib/trpc/client.tsClient-side hooks (useTRPC, TRPCProvider, HydrateClient)
src/app/api/trpc/[trpc]/route.tsHTTP endpoint at /api/trpc

Procedure Levels

LevelAuth RequiredUse Case
publicProcedureNoPublic data (plans, features)
protectedProcedureYesUser-scoped data (profile, settings)
adminProcedureYes + admin roleAdmin operations (user management)

Creating a Router

import { z } from 'zod';
import { router, protectedProcedure } from '../init';
import { db } from '@/lib/db';
import { user } from '@/lib/db/schema';
import { eq } from 'drizzle-orm';

export const userRouter = router({
  me: protectedProcedure.query(async ({ ctx }) => {
    return (
      await db
        .select({ id: user.id, name: user.name, email: user.email })
        .from(user)
        .where(eq(user.id, ctx.session.user.id))
        .limit(1)
    ).at(0);
  }),

  updateProfile: protectedProcedure
    .input(z.object({ name: z.string().min(1).max(100) }))
    .mutation(async ({ ctx, input }) => {
      await db
        .update(user)
        .set({ name: input.name, updatedAt: new Date() })
        .where(eq(user.id, ctx.session.user.id));
      return { success: true };
    }),
});

To register a new router, add it to the appRouter in src/lib/trpc/router.ts.

Server-Side Prefetch

Use prefetch() in server components to load data before the page renders, then hydrate the cache on the client:

import { prefetch } from '@/lib/trpc/server';
import { HydrateClient } from '@/lib/trpc/client';

export default async function ProfilePage() {
  await prefetch((t) => t.user.me.prefetch());

  return (
    <HydrateClient>
      <ProfileClient />
    </HydrateClient>
  );
}

Client-Side Usage

'use client';

import { useTRPC } from '@/lib/trpc/client';
import { useQuery, useMutation } from '@tanstack/react-query';

export function ProfileClient() {
  const trpc = useTRPC();
  const { data: user } = useQuery(trpc.user.me.queryOptions());

  const updateMutation = useMutation(trpc.user.updateProfile.mutationOptions());

  return (
    <div>
      <h1>Hello, {user?.name}</h1>
      <button onClick={() => updateMutation.mutate({ name: 'New Name' })}>Update</button>
    </div>
  );
}

Adding a New Router

  1. Create a file in src/lib/trpc/routers/ (e.g. projects.ts)
  2. Define queries and mutations using the appropriate procedure level
  3. Register the router in src/lib/trpc/router.ts
  4. Use it on the client via trpc.projects.yourProcedure

The types flow automatically — no code generation or manual type imports needed.

API LayerGraphQL