diff --git a/src/controllers/api/nameWeaponController.ts b/src/controllers/api/nameWeaponController.ts
new file mode 100644
index 00000000..7543cbc4
--- /dev/null
+++ b/src/controllers/api/nameWeaponController.ts
@@ -0,0 +1,27 @@
+import { RequestHandler } from "express";
+import { getAccountIdForRequest } from "@/src/services/loginService";
+import { getInventory, updateCurrency } from "@/src/services/inventoryService";
+import { getJSONfromString } from "@/src/helpers/stringHelpers";
+import { TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
+
+interface INameWeaponRequest {
+    ItemName: string;
+}
+
+export const nameWeaponController: RequestHandler = async (req, res) => {
+    const accountId = await getAccountIdForRequest(req);
+    const inventory = await getInventory(accountId);
+    const body = getJSONfromString(req.body.toString()) as INameWeaponRequest;
+    const item = inventory[req.query.Category as string as TEquipmentKey].find(
+        item => item._id.toString() == (req.query.ItemId as string)
+    )!;
+    if (body.ItemName != "") {
+        item.ItemName = body.ItemName;
+    } else {
+        item.ItemName = undefined;
+    }
+    await inventory.save();
+    res.json({
+        InventoryChanges: await updateCurrency("webui" in req.query ? 0 : 15, true, accountId)
+    });
+};
diff --git a/src/controllers/api/upgradesController.ts b/src/controllers/api/upgradesController.ts
index 88c01dc7..25b548e6 100644
--- a/src/controllers/api/upgradesController.ts
+++ b/src/controllers/api/upgradesController.ts
@@ -1,7 +1,7 @@
 import { RequestHandler } from "express";
 import { IUpgradesRequest } from "@/src/types/requestTypes";
 import { FocusSchool, IEquipmentDatabase } from "@/src/types/inventoryTypes/commonInventoryTypes";
-import { IMiscItem, IEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
+import { IMiscItem, TEquipmentKey } from "@/src/types/inventoryTypes/inventoryTypes";
 import { getAccountIdForRequest } from "@/src/services/loginService";
 import { addMiscItems, getInventory, updateCurrency } from "@/src/services/inventoryService";
 
@@ -28,7 +28,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
         switch (operation.UpgradeRequirement) {
             case "/Lotus/Types/Items/MiscItems/OrokinReactor":
             case "/Lotus/Types/Items/MiscItems/OrokinCatalyst":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.Features ??= 0;
                         item.Features |= 1;
@@ -38,7 +38,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
                 break;
             case "/Lotus/Types/Items/MiscItems/UtilityUnlocker":
             case "/Lotus/Types/Items/MiscItems/WeaponUtilityUnlocker":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.Features ??= 0;
                         item.Features |= 2;
@@ -49,7 +49,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
             case "/Lotus/Types/Items/MiscItems/WeaponPrimaryArcaneUnlocker":
             case "/Lotus/Types/Items/MiscItems/WeaponSecondaryArcaneUnlocker":
             case "/Lotus/Types/Items/MiscItems/WeaponMeleeArcaneUnlocker":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.Features ??= 0;
                         item.Features |= 32;
@@ -61,7 +61,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
             case "/Lotus/Types/Items/MiscItems/FormaUmbra":
             case "/Lotus/Types/Items/MiscItems/FormaAura":
             case "/Lotus/Types/Items/MiscItems/FormaStance":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.XP = 0;
                         setSlotPolarity(item, operation.PolarizeSlot, operation.PolarizeValue);
@@ -72,7 +72,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
                 }
                 break;
             case "/Lotus/Types/Items/MiscItems/ModSlotUnlocker":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.ModSlotPurchases ??= 0;
                         item.ModSlotPurchases += 1;
@@ -87,7 +87,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
                 }
                 break;
             case "/Lotus/Types/Items/MiscItems/CustomizationSlotUnlocker":
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         item.CustomizationSlotPurchases ??= 0;
                         item.CustomizationSlotPurchases += 1;
@@ -103,7 +103,7 @@ export const upgradesController: RequestHandler = async (req, res) => {
                 break;
             case "":
                 console.assert(operation.OperationType == "UOT_SWAP_POLARITY");
-                for (const item of inventory[payload.ItemCategory as IEquipmentKey] as IEquipmentDatabase[]) {
+                for (const item of inventory[payload.ItemCategory as TEquipmentKey] as IEquipmentDatabase[]) {
                     if (item._id.toString() == payload.ItemId.$oid) {
                         for (let i = 0; i != operation.PolarityRemap.length; ++i) {
                             if (operation.PolarityRemap[i].Slot != i) {
diff --git a/src/routes/api.ts b/src/routes/api.ts
index 2ed9bdcb..8a059bfe 100644
--- a/src/routes/api.ts
+++ b/src/routes/api.ts
@@ -55,6 +55,7 @@ import { getGuildDojoController } from "@/src/controllers/api/getGuildDojoContro
 import { syndicateSacrificeController } from "../controllers/api/syndicateSacrificeController";
 import { startDojoRecipeController } from "@/src/controllers/api/startDojoRecipeController";
 import { queueDojoComponentDestructionController } from "@/src/controllers/api/queueDojoComponentDestructionController";
+import { nameWeaponController } from "@/src/controllers/api/nameWeaponController";
 
 const apiRouter = express.Router();
 
@@ -120,5 +121,6 @@ apiRouter.post("/upgrades.php", upgradesController);
 apiRouter.post("/guildTech.php", guildTechController);
 apiRouter.post("/syndicateSacrifice.php", syndicateSacrificeController);
 apiRouter.post("/startDojoRecipe.php", startDojoRecipeController);
+apiRouter.post("/nameWeapon.php", nameWeaponController);
 
 export { apiRouter };
diff --git a/src/types/inventoryTypes/inventoryTypes.ts b/src/types/inventoryTypes/inventoryTypes.ts
index 4b4f589a..ec492353 100644
--- a/src/types/inventoryTypes/inventoryTypes.ts
+++ b/src/types/inventoryTypes/inventoryTypes.ts
@@ -59,7 +59,7 @@ export interface ITypeCount {
     ItemCount: number;
 }
 
-export type IEquipmentKey =
+export type TEquipmentKey =
     | "Suits"
     | "LongGuns"
     | "Pistols"
diff --git a/static/webui/script.js b/static/webui/script.js
index 0475a730..6a9d525d 100644
--- a/static/webui/script.js
+++ b/static/webui/script.js
@@ -132,6 +132,9 @@ function updateInventory() {
                 {
                     const td = document.createElement("td");
                     td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
+                    if (item.ItemName) {
+                        td.textContent = item.ItemName + " (" + td.textContent + ")";
+                    }
                     tr.appendChild(td);
                 }
                 {
@@ -144,12 +147,21 @@ function updateInventory() {
                             event.preventDefault();
                             addGearExp("Suits", item.ItemId.$oid, 1_600_000 - item.XP);
                         };
-                        a.textContent = "Make Rank 30";
+                        a.title = "Make Rank 30";
+                        a.innerHTML = ``;
+                        td.appendChild(a);
+                    }
+                    {
+                        const a = document.createElement("a");
+                        a.href = "#";
+                        a.onclick = function (event) {
+                            event.preventDefault();
+                            const name = prompt("Enter new custom name:");
+                            renameGear("Suits", item.ItemId.$oid, name);
+                        };
+                        a.title = "Rename";
+                        a.innerHTML = ``;
                         td.appendChild(a);
-
-                        const span = document.createElement("span");
-                        span.innerHTML = " · ";
-                        td.appendChild(span);
                     }
                     {
                         const a = document.createElement("a");
@@ -158,7 +170,8 @@ function updateInventory() {
                             event.preventDefault();
                             disposeOfGear("Suits", item.ItemId.$oid);
                         };
-                        a.textContent = "Remove";
+                        a.title = "Remove";
+                        a.innerHTML = ``;
                         td.appendChild(a);
                     }
                     tr.appendChild(td);
@@ -173,6 +186,9 @@ function updateInventory() {
                     {
                         const td = document.createElement("td");
                         td.textContent = itemMap[item.ItemType]?.name ?? item.ItemType;
+                        if (item.ItemName) {
+                            td.textContent = item.ItemName + " (" + td.textContent + ")";
+                        }
                         tr.appendChild(td);
                     }
                     {
@@ -185,12 +201,21 @@ function updateInventory() {
                                 event.preventDefault();
                                 addGearExp(category, item.ItemId.$oid, 800_000 - item.XP);
                             };
-                            a.textContent = "Make Rank 30";
+                            a.title = "Make Rank 30";
+                            a.innerHTML = ``;
+                            td.appendChild(a);
+                        }
+                        {
+                            const a = document.createElement("a");
+                            a.href = "#";
+                            a.onclick = function (event) {
+                                event.preventDefault();
+                                const name = prompt("Enter new custom name:");
+                                renameGear(category, item.ItemId.$oid, name);
+                            };
+                            a.title = "Rename";
+                            a.innerHTML = ``;
                             td.appendChild(a);
-
-                            const span = document.createElement("span");
-                            span.innerHTML = " · ";
-                            td.appendChild(span);
                         }
                         {
                             const a = document.createElement("a");
@@ -199,7 +224,8 @@ function updateInventory() {
                                 event.preventDefault();
                                 disposeOfGear(category, item.ItemId.$oid);
                             };
-                            a.textContent = "Remove";
+                            a.title = "Remove";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
                         tr.appendChild(td);
@@ -241,14 +267,10 @@ function updateInventory() {
                                     })
                                 );
                             a.target = "_blank";
-                            a.textContent = "View Stats";
+                            a.title = "View Stats";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
-                        {
-                            const span = document.createElement("span");
-                            span.innerHTML = " · ";
-                            td.appendChild(span);
-                        }
                         {
                             const a = document.createElement("a");
                             a.href = "#";
@@ -256,7 +278,8 @@ function updateInventory() {
                                 event.preventDefault();
                                 disposeOfGear("Upgrades", item.ItemId.$oid);
                             };
-                            a.textContent = "Remove";
+                            a.title = "Remove";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
                         tr.appendChild(td);
@@ -282,12 +305,9 @@ function updateInventory() {
                                 event.preventDefault();
                                 setFingerprint(item.ItemType, item.ItemId, { lvl: maxRank });
                             };
-                            a.textContent = "Max Rank";
+                            a.title = "Max Rank";
+                            a.innerHTML = ``;
                             td.appendChild(a);
-
-                            const span = document.createElement("span");
-                            span.innerHTML = " · ";
-                            td.appendChild(span);
                         }
                         {
                             const a = document.createElement("a");
@@ -296,7 +316,8 @@ function updateInventory() {
                                 event.preventDefault();
                                 disposeOfGear("Upgrades", item.ItemId.$oid);
                             };
-                            a.textContent = "Remove";
+                            a.title = "Remove";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
                         tr.appendChild(td);
@@ -327,14 +348,10 @@ function updateInventory() {
                                 event.preventDefault();
                                 setFingerprint(item.ItemType, item.LastAdded, { lvl: maxRank });
                             };
-                            a.textContent = "Max Rank";
+                            a.title = "Max Rank";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
-                        {
-                            const span = document.createElement("span");
-                            span.innerHTML = " · ";
-                            td.appendChild(span);
-                        }
                         {
                             const a = document.createElement("a");
                             a.href = "#";
@@ -342,7 +359,8 @@ function updateInventory() {
                                 event.preventDefault();
                                 disposeOfItems("Upgrades", item.ItemType, item.ItemCount);
                             };
-                            a.textContent = "Remove";
+                            a.title = "Remove";
+                            a.innerHTML = ``;
                             td.appendChild(a);
                         }
                         tr.appendChild(td);
@@ -432,6 +450,20 @@ function addGearExp(category, oid, xp) {
     });
 }
 
+function renameGear(category, oid, name) {
+    revalidateAuthz(() => {
+        $.post({
+            url: "/api/nameWeapon.php?" + window.authz + "&Category=" + category + "&ItemId=" + oid + "&webui=1",
+            contentType: "text/plain",
+            data: JSON.stringify({
+                ItemName: name
+            })
+        }).done(function () {
+            updateInventory();
+        });
+    });
+}
+
 function disposeOfGear(category, oid) {
     const data = {
         SellCurrency: "SC_RegularCredits",
diff --git a/static/webui/style.css b/static/webui/style.css
index 119d4fd2..341588cd 100644
--- a/static/webui/style.css
+++ b/static/webui/style.css
@@ -20,3 +20,10 @@ body:not(.logged-in) .nav-item.dropdown,
 body:not(.logged-in) #refresh-note {
     display: none;
 }
+
+td.text-end > a > svg {
+    fill: currentColor;
+    height: 1em;
+    margin-left: 0.5em;
+    margin-bottom: 4px; /* to centre the icon */
+}