diff --git a/app/(content)/(user)/[userid]/(profile)/media/page.tsx b/app/(content)/(user)/[userid]/(profile)/media/page.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..0d06dc6f70be1c8d70eee12ece256f4d5f878edc
--- /dev/null
+++ b/app/(content)/(user)/[userid]/(profile)/media/page.tsx
@@ -0,0 +1,7 @@
+export default async function Media() {
+    return (
+        <div>
+            <h1>Media Page WIP</h1>
+        </div>
+    )
+}
\ No newline at end of file
diff --git a/app/(content)/(user)/[userid]/(profile)/with_replies/page.tsx b/app/(content)/(user)/[userid]/(profile)/with_replies/page.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..83676c5918245f147522159d6124ff3fdfad1d13
--- /dev/null
+++ b/app/(content)/(user)/[userid]/(profile)/with_replies/page.tsx
@@ -0,0 +1,7 @@
+export default async function WithReplies() {
+    return (
+        <div>
+            <h1>WithReplies Page WIP</h1>
+        </div>
+    )
+}
\ No newline at end of file
diff --git a/app/api/followers/route.ts b/app/api/followers/route.ts
deleted file mode 100644
index cc327201fc2833606e01beb869bff9515f15ddb7..0000000000000000000000000000000000000000
--- a/app/api/followers/route.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { db } from "@/lib/db"
-import { getCurrentUser } from "@/lib/session"
-import { revalidatePath } from "next/cache"
-import { NextRequest, NextResponse } from "next/server"
-
-export async function GET(req: NextRequest) {
-    const sessionUser = await getCurrentUser()
-
-    if (!sessionUser) {
-        return NextResponse.json({ status: 401, message: 'Unauthorized' })
-    }
-    let follows = undefined
-
-    try {
-        follows = await db.follows.findMany({
-            where: {
-                followerId: sessionUser.id
-            }
-        })
-    } catch (error) {
-        console.log("error", error)
-    }
-
-    return NextResponse.json({ status: 200, message: "fetched follows", follows })
-}
-
-export async function PUT(req: NextRequest) {
-    const sessionUser = await getCurrentUser()
-
-    const data = await req.json()
-
-    if (!sessionUser) {
-        return NextResponse.json({ status: 401, message: 'Unauthorized' })
-    }
-
-    try {
-        const dbUser = await db.user.findFirst({
-            where: {
-                id: sessionUser.id
-            }
-        })
-
-        const follow = await db.follows.findFirst({
-            where: {
-                followerId: sessionUser.id,
-                followingId: data.followingId
-            }
-        })
-        console.log("follow", follow)
-
-        if (follow) {
-            // User is already following, so unfollow
-            console.log("delete follow")
-            const delfollow = await db.follows.delete({
-                where: {
-                    followerId_followingId: {
-                        followerId: sessionUser.id,
-                        followingId: data.followingId
-                    }
-
-                }
-            })
-            console.log("del follow:", delfollow)
-        } else {
-            // User is not following, so follow
-            console.log("create follow")
-            await db.follows.create({
-                data: {
-                    followerId: sessionUser.id,
-                    followingId: data.followingId
-                },
-            })
-
-        }
-    } catch (error) {
-        console.log("err", error)
-    }
-    const path = req.nextUrl.searchParams.get('path') || '/'
-    revalidatePath(path)
-
-    return NextResponse.json({ status: 200, message: 'Follow handled' })
-}
\ No newline at end of file
diff --git a/app/api/users/[id]/route.ts b/app/api/users/[id]/route.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c0bb2b07c7cd882296f076a11e6e33d9cc534e29
--- /dev/null
+++ b/app/api/users/[id]/route.ts
@@ -0,0 +1,102 @@
+import { db } from "@/lib/db"
+import { NextResponse } from "next/server"
+import { z } from "zod"
+
+export async function GET(request: Request, context: { params: { id: string } }) {
+    const { id } = context.params
+
+    const idSchema = z.string().cuid()
+    const zod = idSchema.safeParse(id)
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        const user = await db.user.findUnique({
+            where: {
+                id,
+            },
+
+            select: {
+                id: true,
+                name: true,
+                username: true,
+                email: true,
+                image: true,
+                banner: true,
+
+                createdAt: true,
+                bio: true,
+                location: true,
+                followers: true,
+                following: true,
+
+                _count: {
+                    select: {
+                        followers: true,
+                        following: true,
+                    },
+                },
+            },
+        })
+
+        return NextResponse.json(user, { status: 200 })
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
+
+export async function PUT(request: Request) {
+    const {
+        userId,
+        name,
+        bio,
+        location,
+        banner,
+        image,
+    } = await request.json()
+
+    const userSchema = z
+        .object({
+            userId: z.string().cuid(),
+            name: z.string().min(1).max(50),
+            bio: z.string().max(160),
+            location: z.string().max(30),
+            banner: z.string(),
+            image: z.string(),
+        })
+        .strict()
+
+    const zod = userSchema.safeParse({
+        userId,
+        name,
+        bio,
+        location,
+        banner,
+        image,
+    })
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        const user = await db.user.update({
+            where: {
+                id: userId,
+            },
+            data: {
+                name,
+                bio,
+                location,
+                banner,
+                image,
+            },
+        })
+
+        return NextResponse.json(user, { status: 200 })
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
\ No newline at end of file
diff --git a/app/api/users/favgameslist/route.ts b/app/api/users/favgameslist/route.ts
index 7b06bead77749d765ee284b985b0063922027025..967f901545abfd58534d1ed046c04023319a6afb 100644
--- a/app/api/users/favgameslist/route.ts
+++ b/app/api/users/favgameslist/route.ts
@@ -4,13 +4,13 @@ import { revalidatePath } from "next/cache"
 import { NextRequest, NextResponse } from "next/server"
 
 export async function PUT(req: NextRequest) {
-    const user = await getCurrentUser()
+    const session = await getCurrentUser()
 
-    if (!user) {
+    if (!session) {
         return NextResponse.json({ status: 401, message: 'Unauthorized' })
     }
 
-    const userId = user.id
+    const userId = session.id
     const data = await req.json()
     data.gameId = parseInt(data.gameId)
 
diff --git a/app/api/users/follow/route.ts b/app/api/users/follow/route.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3c6dc932a33610d9706e5924ef3781e7b2263c11
--- /dev/null
+++ b/app/api/users/follow/route.ts
@@ -0,0 +1,129 @@
+import { db } from "@/lib/db"
+import { getCurrentUser } from "@/lib/session"
+import { NextResponse } from "next/server"
+import { z } from "zod"
+
+// get following or followers information
+export async function GET(request: Request) {
+    const { searchParams } = new URL(request.url)
+    const userId = searchParams.get("userId") || undefined
+    const type = searchParams.get("type") || undefined
+
+    const userIdSchema = z.string().cuid().optional()
+    const zod = userIdSchema.safeParse(userId)
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        if (type === "followers") {
+            const followers = await db.user
+                .findUnique({
+                    where: {
+                        id: userId,
+                    },
+                })
+                .followers()
+            return NextResponse.json(followers, { status: 200 })
+        } else if (type === "following") {
+            const following = await db.user
+                .findUnique({
+                    where: {
+                        id: userId,
+                    },
+                })
+                .following()
+
+            return NextResponse.json(following, { status: 200 })
+        }
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
+
+// follow a user
+export async function PUT(request: Request) {
+    const session = await getCurrentUser()
+    const { userId } = await request.json()
+
+    const followerIdSchema = z
+        .object({
+            userId: z.string().cuid(),
+        })
+        .strict()
+
+    const zod = followerIdSchema.safeParse({ userId })
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        await db.user.update({
+            where: {
+                id: userId,
+            },
+
+            data: {
+                followers: {
+                    connect: {
+                        id: session?.id,
+                    },
+                },
+            },
+        })
+
+        return NextResponse.json(
+            {
+                message: "followed",
+            }, { status: 200 }
+        )
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
+
+// unfollow a user
+export async function DELETE(request: Request) {
+    const session = await getCurrentUser()
+    const { searchParams } = new URL(request.url)
+
+    const userId = searchParams.get("userId") || undefined
+
+    const followerIdSchema = z
+        .object({
+            userId: z.string().cuid(),
+        })
+        .strict()
+
+    const zod = followerIdSchema.safeParse({ userId })
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        await db.user.update({
+            where: {
+                id: userId,
+            },
+
+            data: {
+                followers: {
+                    disconnect: {
+                        id: session?.id,
+                    },
+                },
+            },
+        })
+
+        return NextResponse.json(
+            {
+                message: "unfollowed",
+            }, { status: 200 },
+        )
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
\ No newline at end of file
diff --git a/app/api/users/route.ts b/app/api/users/route.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e0611fd2ca092f2ec42df17c1c6a0205df646740
--- /dev/null
+++ b/app/api/users/route.ts
@@ -0,0 +1,44 @@
+import { db } from "@/lib/db"
+import { NextResponse } from "next/server"
+import { z } from "zod"
+
+// get all other users
+export async function GET(request: Request) {
+    const { searchParams } = new URL(request.url)
+    const id = searchParams.get("id") || undefined
+    const idSchema = z.string().cuid().optional()
+
+    const zod = idSchema.safeParse(id)
+
+    if (!zod.success) {
+        return NextResponse.json(zod.error, { status: 400 })
+    }
+
+    try {
+        const users = await db.user.findMany({
+            where: {
+                NOT: {
+                    id,
+                },
+            },
+
+            orderBy: {
+                createdAt: "desc",
+            },
+
+            select: {
+                id: true,
+                name: true,
+                username: true,
+                email: true,
+                image: true,
+                following: true,
+                followers: true,
+            },
+        })
+
+        return NextResponse.json(users, { status: 200 })
+    } catch (error: any) {
+        return NextResponse.json(error.message, { status: 500 })
+    }
+}
\ No newline at end of file
diff --git a/components/following-button.tsx b/components/following-button.tsx
index b5eb3f4e51b564dad1cd30b38b77fecce04e4dd7..46342824a4bcd0565effefd29f393c4b108bcf42 100644
--- a/components/following-button.tsx
+++ b/components/following-button.tsx
@@ -1,6 +1,6 @@
 "use client"
 
-import { Follows, Prisma } from '@prisma/client'
+import { Prisma } from '@prisma/client'
 import { useSession } from 'next-auth/react'
 import { usePathname } from "next/navigation"
 import { useEffect, useState } from 'react'
@@ -31,12 +31,12 @@ export default function FollowButton({ user, followingId }: { user: UserWithFoll
     async function fetchFollows() {
 
         try {
-            const response = await fetch('/api/followers')
+            const response = await fetch('/api/users/follow')
 
             const data = await response.json()
             setFollows(data.follows)
             setIsFollowing(false)
-            data.follows?.forEach((f: Follows) => {
+            data.follows?.forEach((f: any) => {
 
                 if (f.followerId == user.id && f.followingId == followingId) {
                     setIsFollowing(true)
@@ -56,7 +56,7 @@ export default function FollowButton({ user, followingId }: { user: UserWithFoll
     async function handleFollow(e: any) {
         e.preventDefault()
 
-        const response = await fetch('/api/followers', {
+        const response = await fetch('/api/users/follow', {
             method: 'PUT',
             body: JSON.stringify({ user, followingId })
         })
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 9deaae8759c1e6d52d9ef69b7caa4e9be0174f0d..d6b3ef1cdc15ec826b97a8e27954672bc783f996 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -81,24 +81,12 @@ model User {
     regweets Regweet[]
     likes    Like[]
 
-    following Follows[] @relation("following")
-    followers Follows[] @relation("follower")
+    following User[] @relation("followers")
+    followers User[] @relation("followers")
 
     @@map("users")
 }
 
-model Follows {
-    followerId  String
-    followingId String
-    createdAt   DateTime @default(now()) @map("created_at")
-
-    follower  User @relation("following", fields: [followerId], references: [id])
-    following User @relation("follower", fields: [followingId], references: [id])
-
-    @@id([followerId, followingId])
-    @@map("follows")
-}
-
 model Gweet {
     id        String   @id @default(cuid())
     authorId  String   @map("user_id")