diff --git a/src/components/navigation/left/HomeSidebar.tsx b/src/components/navigation/left/HomeSidebar.tsx
index d9cea635459f236d75d7d7a6ece66f96ada51fe3..187680b4f678b03f3ad8c091a055efd6ae36a00d 100644
--- a/src/components/navigation/left/HomeSidebar.tsx
+++ b/src/components/navigation/left/HomeSidebar.tsx
@@ -23,7 +23,6 @@ import { Unreads } from "../../../redux/reducers/unreads";
 
 import { useIntermediate } from "../../../context/intermediate/Intermediate";
 import { AppContext } from "../../../context/revoltjs/RevoltClient";
-import { useDMs, useForceUpdate } from "../../../context/revoltjs/hooks";
 
 import Category from "../../ui/Category";
 import placeholderSVG from "../items/placeholder.svg";
diff --git a/src/context/revoltjs/hooks.ts b/src/context/revoltjs/hooks.ts
index 956c0976c3574623179ace7d71d273631a781f94..59edf36699ca77526b07d3040cb978c615b77c78 100644
--- a/src/context/revoltjs/hooks.ts
+++ b/src/context/revoltjs/hooks.ts
@@ -1,7 +1,4 @@
-import isEqual from "lodash.isequal";
 import { Client, PermissionCalculator } from "revolt.js";
-import { Channels, Servers, Users } from "revolt.js/dist/api/objects";
-import Collection from "revolt.js/dist/maps/Collection";
 
 import { useContext, useEffect, useState } from "preact/hooks";
 
@@ -30,95 +27,6 @@ export function useForceUpdate(context?: HookContext): HookContext {
     return { client, forceUpdate: () => updateState(Math.random()) };
 }
 
-// TODO: utils.d.ts maybe?
-type PickProperties<T, U> = Pick<
-    T,
-    {
-        [K in keyof T]: T[K] extends U ? K : never;
-    }[keyof T]
->;
-
-// The keys in Client that are an object
-// for some reason undefined keeps appearing despite there being no reason to so it's filtered out
-type ClientCollectionKey = Exclude<
-    keyof PickProperties<Client, Collection<any>>,
-    undefined
->;
-
-function useObject(
-    type: ClientCollectionKey,
-    id?: string | string[],
-    context?: HookContext,
-) {
-    const ctx = useForceUpdate(context);
-
-    function update(target: any) {
-        if (
-            typeof id === "string"
-                ? target === id
-                : Array.isArray(id)
-                ? id.includes(target)
-                : true
-        ) {
-            ctx.forceUpdate();
-        }
-    }
-
-    const map = ctx.client[type];
-    useEffect(() => {
-        map.addListener("update", update);
-        return () => map.removeListener("update", update);
-    }, [id]);
-
-    return typeof id === "string"
-        ? map.get(id)
-        : Array.isArray(id)
-        ? id.map((x) => map.get(x))
-        : map.toArray();
-}
-
-export function useMember(id?: string, context?: HookContext) {
-    if (typeof id === "undefined") return;
-    return useObject("members", id, context) as
-        | Readonly<Servers.Member>
-        | undefined;
-}
-
-export function useDMs(context?: HookContext) {
-    const ctx = useForceUpdate(context);
-
-    function mutation(target: string) {
-        const channel = ctx.client.channels.get(target);
-        if (channel) {
-            if (
-                channel.channel_type === "DirectMessage" ||
-                channel.channel_type === "Group"
-            ) {
-                ctx.forceUpdate();
-            }
-        }
-    }
-
-    const map = ctx.client.channels;
-    useEffect(() => {
-        map.addListener("update", mutation);
-        return () => map.removeListener("update", mutation);
-    }, []);
-
-    return map
-        .toArray()
-        .filter(
-            (x) =>
-                x.channel_type === "DirectMessage" ||
-                x.channel_type === "Group" ||
-                x.channel_type === "SavedMessages",
-        ) as (
-        | Channels.GroupChannel
-        | Channels.DirectMessageChannel
-        | Channels.SavedMessagesChannel
-    )[];
-}
-
 export function useUserPermission(id: string, context?: HookContext) {
     const ctx = useForceUpdate(context);
 
@@ -192,43 +100,3 @@ export function useServerPermission(id: string, context?: HookContext) {
     return calculator.forServer(id);
 }
 //#endregion
-
-//#region Hooks v2 (deprecated)
-type CollectionKeys = Exclude<
-    keyof PickProperties<Client, Collection<any>>,
-    undefined
->;
-
-interface Depedency {
-    key: CollectionKeys;
-    id?: string;
-}
-
-export function useDataDeprecated<T>(
-    cb: (client: Client) => T,
-    dependencies: Depedency[],
-): T {
-    // ! FIXME: not sure if this may cost a lot
-    const client = useContext(AppContext);
-    const [data, setData] = useState(cb(client));
-
-    useEffect(() => {
-        let fns = dependencies.map((dependency) => {
-            function update() {
-                let generated = cb(client);
-                if (!isEqual(data, generated)) {
-                    setData(generated);
-                }
-            }
-
-            client[dependency.key].addListener("update", update);
-            return () =>
-                client[dependency.key].removeListener("update", update);
-        });
-
-        return () => fns.forEach((x) => x());
-    }, [data]);
-
-    return data;
-}
-//#endregion
diff --git a/src/mobx/index.ts b/src/mobx/index.ts
index 6cb7615f3250dd90c886b7e1b71e97cec8c66cb1..076c06207c85723d6ebc369d75f3df7eb082684e 100644
--- a/src/mobx/index.ts
+++ b/src/mobx/index.ts
@@ -17,6 +17,7 @@ import {
 } from "revolt.js/dist/api/objects";
 import {
     RemoveChannelField,
+    RemoveMemberField,
     RemoveServerField,
     RemoveUserField,
 } from "revolt.js/dist/api/routes";
@@ -251,10 +252,51 @@ export class Server {
     }
 }
 
+export class Member {
+    _id: Servers.MemberCompositeKey;
+    nickname: Nullable<string> = null;
+    avatar: Nullable<Attachment> = null;
+    roles: Nullable<string[]> = null;
+
+    constructor(data: Servers.Member) {
+        this._id = data._id;
+        this.nickname = toNullable(data.nickname);
+        this.avatar = toNullable(data.avatar);
+        this.roles = toNullable(data.roles);
+
+        makeAutoObservable(this);
+    }
+
+    @action update(data: Partial<Servers.Member>, clear?: RemoveMemberField) {
+        const apply = (key: string) => {
+            // This code has been tested.
+            // @ts-expect-error
+            if (data[key] && !isEqual(this[key], data[key])) {
+                // @ts-expect-error
+                this[key] = data[key];
+            }
+        };
+
+        switch (clear) {
+            case "Nickname":
+                this.nickname = null;
+                break;
+            case "Avatar":
+                this.avatar = null;
+                break;
+        }
+
+        apply("nickname");
+        apply("avatar");
+        apply("roles");
+    }
+}
+
 export class DataStore {
     @observable users = new Map<string, User>();
     @observable channels = new Map<string, Channel>();
     @observable servers = new Map<string, Server>();
+    @observable members = new Map<Servers.MemberCompositeKey, Member>();
 
     constructor() {
         makeAutoObservable(this);