diff --git a/apps/web/src/app/[locale]/(admin)/dashboard.tsx b/apps/web/src/app/[locale]/(admin)/dashboard.tsx
index 10a9fb48e..1b2a434af 100644
--- a/apps/web/src/app/[locale]/(admin)/dashboard.tsx
+++ b/apps/web/src/app/[locale]/(admin)/dashboard.tsx
@@ -15,7 +15,7 @@ import {
} from "@/app/[locale]/(admin)/app-card";
import { Spinner } from "@/components/spinner";
import { Trans } from "@/components/trans";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
export default function Dashboard() {
const { data } = trpc.dashboard.info.useQuery();
diff --git a/apps/web/src/app/[locale]/(admin)/events/past-events.tsx b/apps/web/src/app/[locale]/(admin)/events/past-events.tsx
index 7bbac0727..16000b9c4 100644
--- a/apps/web/src/app/[locale]/(admin)/events/past-events.tsx
+++ b/apps/web/src/app/[locale]/(admin)/events/past-events.tsx
@@ -10,7 +10,7 @@ import {
} from "@/app/components/empty-state";
import { Spinner } from "@/components/spinner";
import { Trans } from "@/components/trans";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
export function PastEvents() {
const { data } = trpc.scheduledEvents.list.useQuery({
diff --git a/apps/web/src/app/[locale]/(admin)/events/upcoming-events.tsx b/apps/web/src/app/[locale]/(admin)/events/upcoming-events.tsx
index 437212b1c..52210f0bc 100644
--- a/apps/web/src/app/[locale]/(admin)/events/upcoming-events.tsx
+++ b/apps/web/src/app/[locale]/(admin)/events/upcoming-events.tsx
@@ -10,7 +10,7 @@ import {
} from "@/app/components/empty-state";
import { Spinner } from "@/components/spinner";
import { Trans } from "@/components/trans";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
export function UpcomingEvents() {
const { data } = trpc.scheduledEvents.list.useQuery({ period: "upcoming" });
diff --git a/apps/web/src/app/[locale]/(admin)/polls/user-polls.tsx b/apps/web/src/app/[locale]/(admin)/polls/user-polls.tsx
index 3081cd21c..1b8afee49 100644
--- a/apps/web/src/app/[locale]/(admin)/polls/user-polls.tsx
+++ b/apps/web/src/app/[locale]/(admin)/polls/user-polls.tsx
@@ -24,7 +24,7 @@ import { PollStatusBadge } from "@/components/poll-status";
import { Spinner } from "@/components/spinner";
import { Trans } from "@/components/trans";
import { VisibilityTrigger } from "@/components/visibility-trigger";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
function PollCount({ count }: { count?: number }) {
return {count || 0};
diff --git a/apps/web/src/app/[locale]/(admin)/settings/billing/billing-page.tsx b/apps/web/src/app/[locale]/(admin)/settings/billing/billing-page.tsx
index ce7f01c41..a8c911d86 100644
--- a/apps/web/src/app/[locale]/(admin)/settings/billing/billing-page.tsx
+++ b/apps/web/src/app/[locale]/(admin)/settings/billing/billing-page.tsx
@@ -14,7 +14,7 @@ import {
} from "@/components/settings/settings";
import { Trans } from "@/components/trans";
import { useSubscription } from "@/contexts/plan";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
import { BillingPlans, PricingData } from "./billing-plans";
diff --git a/apps/web/src/app/[locale]/(admin)/settings/profile/delete-account-dialog.tsx b/apps/web/src/app/[locale]/(admin)/settings/profile/delete-account-dialog.tsx
index 04c2ca7e1..236dc23ab 100644
--- a/apps/web/src/app/[locale]/(admin)/settings/profile/delete-account-dialog.tsx
+++ b/apps/web/src/app/[locale]/(admin)/settings/profile/delete-account-dialog.tsx
@@ -17,8 +17,8 @@ import { useForm } from "react-hook-form";
import { Trans } from "@/components/trans";
import { useTranslation } from "@/i18n/client";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
export function DeleteAccountDialog({
email,
diff --git a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-picture.tsx b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-picture.tsx
index e12a3b42f..0906f5315 100644
--- a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-picture.tsx
+++ b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-picture.tsx
@@ -9,8 +9,8 @@ import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
import { IfCloudHosted } from "@/contexts/environment";
import { useTranslation } from "@/i18n/client";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
const allowedMimeTypes = z.enum(["image/jpeg", "image/png"]);
diff --git a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-settings.tsx b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-settings.tsx
index 09f259011..40e12c58d 100644
--- a/apps/web/src/app/[locale]/(admin)/settings/profile/profile-settings.tsx
+++ b/apps/web/src/app/[locale]/(admin)/settings/profile/profile-settings.tsx
@@ -12,7 +12,7 @@ import { useForm } from "react-hook-form";
import { ProfilePicture } from "@/app/[locale]/(admin)/settings/profile/profile-picture";
import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
export const ProfileSettings = () => {
const { user, refresh } = useUser();
diff --git a/apps/web/src/app/[locale]/(auth)/register/register-page.tsx b/apps/web/src/app/[locale]/(auth)/register/register-page.tsx
index 2fdbc808d..829123fbc 100644
--- a/apps/web/src/app/[locale]/(auth)/register/register-page.tsx
+++ b/apps/web/src/app/[locale]/(auth)/register/register-page.tsx
@@ -23,8 +23,8 @@ import { z } from "zod";
import { VerifyCode } from "@/components/auth/auth-forms";
import { AuthCard } from "@/components/auth/auth-layout";
import { Trans } from "@/components/trans";
+import { trpc } from "@/trpc/client";
import { useDayjs } from "@/utils/dayjs";
-import { trpc } from "@/utils/trpc/client";
const registerFormSchema = z.object({
name: z.string().nonempty().max(100),
diff --git a/apps/web/src/app/[locale]/auth/login/login-page.tsx b/apps/web/src/app/[locale]/auth/login/login-page.tsx
index bca988884..30a75a8b6 100644
--- a/apps/web/src/app/[locale]/auth/login/login-page.tsx
+++ b/apps/web/src/app/[locale]/auth/login/login-page.tsx
@@ -8,8 +8,8 @@ import { Logo } from "@/components/logo";
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
import { Skeleton } from "@/components/skeleton";
import { Trans } from "@/components/trans";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
type PageProps = { magicLink: string; email: string };
diff --git a/apps/web/src/app/[locale]/invite/[urlId]/layout.tsx b/apps/web/src/app/[locale]/invite/[urlId]/layout.tsx
index c456865c0..06d1126de 100644
--- a/apps/web/src/app/[locale]/invite/[urlId]/layout.tsx
+++ b/apps/web/src/app/[locale]/invite/[urlId]/layout.tsx
@@ -5,7 +5,7 @@ import React from "react";
import { LegacyPollContextProvider } from "@/components/poll/poll-context-provider";
import { VisibilityProvider } from "@/components/visibility";
import { PermissionsContext } from "@/contexts/permissions";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
import Loader from "./loading";
diff --git a/apps/web/src/app/providers.tsx b/apps/web/src/app/providers.tsx
index bbe6abe43..0cd76514f 100644
--- a/apps/web/src/app/providers.tsx
+++ b/apps/web/src/app/providers.tsx
@@ -8,9 +8,9 @@ import { useState } from "react";
import { UserProvider } from "@/components/user-provider";
import { I18nProvider } from "@/i18n/client";
+import { trpcConfig } from "@/trpc/client/config";
import { AppRouter } from "@/trpc/routers";
import { ConnectedDayjsProvider } from "@/utils/dayjs";
-import { trpcConfig } from "@/utils/trpc/config";
export const trpc = createTRPCReact({
unstable_overrides: {
diff --git a/apps/web/src/components/create-poll.tsx b/apps/web/src/components/create-poll.tsx
index 73074622e..13d18cf97 100644
--- a/apps/web/src/components/create-poll.tsx
+++ b/apps/web/src/components/create-poll.tsx
@@ -17,9 +17,9 @@ import { useUnmount } from "react-use";
import { PollSettingsForm } from "@/components/forms/poll-settings";
import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
+import { trpc } from "@/trpc/client";
import { setCookie } from "@/utils/cookies";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
import { NewEventData, PollDetailsForm, PollOptionsForm } from "./forms";
diff --git a/apps/web/src/components/discussion/discussion.tsx b/apps/web/src/components/discussion/discussion.tsx
index 8dbe5eeb3..70361fd18 100644
--- a/apps/web/src/components/discussion/discussion.tsx
+++ b/apps/web/src/components/discussion/discussion.tsx
@@ -36,8 +36,8 @@ import { Trans } from "@/components/trans";
import { usePermissions } from "@/contexts/permissions";
import { usePoll } from "@/contexts/poll";
import { useRole } from "@/contexts/role";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
import { requiredString } from "../../utils/form-validation";
import TruncatedLinkify from "../poll/truncated-linkify";
diff --git a/apps/web/src/components/layouts/poll-layout.tsx b/apps/web/src/components/layouts/poll-layout.tsx
index f49502d84..1e33851f1 100644
--- a/apps/web/src/components/layouts/poll-layout.tsx
+++ b/apps/web/src/components/layouts/poll-layout.tsx
@@ -32,7 +32,7 @@ import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
import { usePlan } from "@/contexts/plan";
import { usePoll } from "@/contexts/poll";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
const AdminControls = () => {
return (
diff --git a/apps/web/src/components/participant-dropdown.tsx b/apps/web/src/components/participant-dropdown.tsx
index a4bfbeb80..5b47e86f5 100644
--- a/apps/web/src/components/participant-dropdown.tsx
+++ b/apps/web/src/components/participant-dropdown.tsx
@@ -37,9 +37,9 @@ import { z } from "zod";
import { OptimizedAvatarImage } from "@/components/optimized-avatar-image";
import { useDeleteParticipantMutation } from "@/components/poll/mutations";
import { Trans } from "@/components/trans";
+import { trpc } from "@/trpc/client";
import { useFormValidation } from "@/utils/form-validation";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
export const ParticipantDropdown = ({
participant,
diff --git a/apps/web/src/components/participants-provider.tsx b/apps/web/src/components/participants-provider.tsx
index 8cfddade4..826ce203c 100644
--- a/apps/web/src/components/participants-provider.tsx
+++ b/apps/web/src/components/participants-provider.tsx
@@ -3,8 +3,8 @@ import * as React from "react";
import { useVisibility } from "@/components/visibility";
import { usePermissions } from "@/contexts/permissions";
-import { trpc } from "@/utils/trpc/client";
-import { Vote } from "@/utils/trpc/types";
+import { trpc } from "@/trpc/client";
+import { Vote } from "@/trpc/client/types";
import { useRequiredContext } from "./use-required-context";
diff --git a/apps/web/src/components/poll-context.tsx b/apps/web/src/components/poll-context.tsx
index fe6837c44..2f9c6aa6d 100644
--- a/apps/web/src/components/poll-context.tsx
+++ b/apps/web/src/components/poll-context.tsx
@@ -5,13 +5,13 @@ import { TrashIcon } from "lucide-react";
import { useTranslation } from "next-i18next";
import React from "react";
+import { GetPollApiResponse, Vote } from "@/trpc/client/types";
import {
getDuration,
ParsedDateOption,
ParsedTimeSlotOption,
} from "@/utils/date-time-utils";
import { useDayjs } from "@/utils/dayjs";
-import { GetPollApiResponse, Vote } from "@/utils/trpc/types";
import ErrorPage from "./error-page";
import { useParticipants } from "./participants-provider";
diff --git a/apps/web/src/components/poll/desktop-poll/participant-row.tsx b/apps/web/src/components/poll/desktop-poll/participant-row.tsx
index ea8046b3f..4c4c45c96 100644
--- a/apps/web/src/components/poll/desktop-poll/participant-row.tsx
+++ b/apps/web/src/components/poll/desktop-poll/participant-row.tsx
@@ -13,7 +13,7 @@ import { usePoll } from "@/components/poll-context";
import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
import { usePermissions } from "@/contexts/permissions";
-import { Vote } from "@/utils/trpc/types";
+import { Vote } from "@/trpc/client/types";
import VoteIcon from "../vote-icon";
import ParticipantRowForm from "./participant-row-form";
diff --git a/apps/web/src/components/poll/manage-poll/delete-poll-dialog.tsx b/apps/web/src/components/poll/manage-poll/delete-poll-dialog.tsx
index 307c7c636..9c1711cf9 100644
--- a/apps/web/src/components/poll/manage-poll/delete-poll-dialog.tsx
+++ b/apps/web/src/components/poll/manage-poll/delete-poll-dialog.tsx
@@ -10,8 +10,8 @@ import { useRouter } from "next/navigation";
import * as React from "react";
import { Trans } from "@/components/trans";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
export const DeletePollDialog: React.FunctionComponent<{
open: boolean;
diff --git a/apps/web/src/components/poll/mutations.ts b/apps/web/src/components/poll/mutations.ts
index a973d7917..503aa3d29 100644
--- a/apps/web/src/components/poll/mutations.ts
+++ b/apps/web/src/components/poll/mutations.ts
@@ -1,6 +1,6 @@
import { usePoll } from "@/components/poll-context";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
import { ParticipantForm } from "./types";
diff --git a/apps/web/src/components/poll/notifications-toggle.tsx b/apps/web/src/components/poll/notifications-toggle.tsx
index c78e84a46..5ff2c82f1 100644
--- a/apps/web/src/components/poll/notifications-toggle.tsx
+++ b/apps/web/src/components/poll/notifications-toggle.tsx
@@ -9,8 +9,8 @@ import * as React from "react";
import { Skeleton } from "@/components/skeleton";
import { Trans } from "@/components/trans";
import { useUser } from "@/components/user-provider";
+import { trpc } from "@/trpc/client";
import { usePostHog } from "@/utils/posthog";
-import { trpc } from "@/utils/trpc/client";
import { usePoll } from "../poll-context";
diff --git a/apps/web/src/components/poll/use-touch-beacon.ts b/apps/web/src/components/poll/use-touch-beacon.ts
index ac2f5eca6..0085e183e 100644
--- a/apps/web/src/components/poll/use-touch-beacon.ts
+++ b/apps/web/src/components/poll/use-touch-beacon.ts
@@ -1,7 +1,7 @@
import { useMount } from "react-use";
import { usePoll } from "@/contexts/poll";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
/**
* Touching a poll updates a column with the current date. This information is used to
diff --git a/apps/web/src/components/user-provider.tsx b/apps/web/src/components/user-provider.tsx
index 3f1ed62d3..464e0d0bb 100644
--- a/apps/web/src/components/user-provider.tsx
+++ b/apps/web/src/components/user-provider.tsx
@@ -8,7 +8,7 @@ import { useSubscription } from "@/contexts/plan";
import { PostHogProvider } from "@/contexts/posthog";
import { PreferencesProvider } from "@/contexts/preferences";
import { useTranslation } from "@/i18n/client";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
import { useRequiredContext } from "./use-required-context";
diff --git a/apps/web/src/contexts/plan.tsx b/apps/web/src/contexts/plan.tsx
index aea2355e3..b7d3f4e10 100644
--- a/apps/web/src/contexts/plan.tsx
+++ b/apps/web/src/contexts/plan.tsx
@@ -3,8 +3,8 @@ import { Badge } from "@rallly/ui/badge";
import React from "react";
import { Trans } from "@/components/trans";
+import { trpc } from "@/trpc/client";
import { isSelfHosted } from "@/utils/constants";
-import { trpc } from "@/utils/trpc/client";
export const useSubscription = () => {
const { data } = trpc.user.subscription.useQuery(undefined, {
diff --git a/apps/web/src/contexts/poll.tsx b/apps/web/src/contexts/poll.tsx
index 0b801078e..adb7b0e32 100644
--- a/apps/web/src/contexts/poll.tsx
+++ b/apps/web/src/contexts/poll.tsx
@@ -1,7 +1,7 @@
import { useParams } from "next/navigation";
import React from "react";
-import { trpc } from "@/utils/trpc/client";
+import { trpc } from "@/trpc/client";
export const usePoll = () => {
const params = useParams<{ urlId: string }>();
diff --git a/apps/web/src/pages/_app.tsx b/apps/web/src/pages/_app.tsx
index 71ef713b9..64799f1ba 100644
--- a/apps/web/src/pages/_app.tsx
+++ b/apps/web/src/pages/_app.tsx
@@ -14,8 +14,8 @@ import React from "react";
import Maintenance from "@/components/maintenance";
import { UserProvider } from "@/components/user-provider";
import { I18nProvider } from "@/i18n/client";
+import { trpc } from "@/trpc/client";
import { ConnectedDayjsProvider } from "@/utils/dayjs";
-import { trpc } from "@/utils/trpc/client";
import { NextPageWithLayout } from "../types";
diff --git a/apps/web/src/utils/trpc/client.ts b/apps/web/src/trpc/client.ts
similarity index 78%
rename from apps/web/src/utils/trpc/client.ts
rename to apps/web/src/trpc/client.ts
index d5017dee2..0279218ca 100644
--- a/apps/web/src/utils/trpc/client.ts
+++ b/apps/web/src/trpc/client.ts
@@ -1,7 +1,7 @@
import { createTRPCNext } from "@trpc/next";
+import { trpcConfig } from "@/trpc/client/config";
import type { AppRouter } from "@/trpc/routers";
-import { trpcConfig } from "@/utils/trpc/config";
export const trpc = createTRPCNext({
config() {
diff --git a/apps/web/src/utils/trpc/config.ts b/apps/web/src/trpc/client/config.ts
similarity index 100%
rename from apps/web/src/utils/trpc/config.ts
rename to apps/web/src/trpc/client/config.ts
diff --git a/apps/web/src/utils/trpc/types.ts b/apps/web/src/trpc/client/types.ts
similarity index 100%
rename from apps/web/src/utils/trpc/types.ts
rename to apps/web/src/trpc/client/types.ts