diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js
index 45bb96c26e..a9baf9be0c 100644
--- a/web_src/js/features/common-global.js
+++ b/web_src/js/features/common-global.js
@@ -211,7 +211,7 @@ export function initGlobalLinkActions() {
         };
         for (const [key, value] of Object.entries(dataArray)) {
           if (key && key.startsWith('data')) {
-            postData[key.substr(4)] = value;
+            postData[key.slice(4)] = value;
           }
           if (key === 'id') {
             postData['id'] = value;
diff --git a/web_src/js/features/common-issue.js b/web_src/js/features/common-issue.js
index d7095a54a3..e894816fb6 100644
--- a/web_src/js/features/common-issue.js
+++ b/web_src/js/features/common-issue.js
@@ -20,7 +20,7 @@ export function initCommonIssue() {
     const issueIDs = $('.issue-checkbox').children('input:checked').map((_, el) => {
       return el.getAttribute('data-issue-id');
     }).get().join(',');
-    if (elementId === '0' && url.substr(-9) === '/assignee') {
+    if (elementId === '0' && url.slice(-9) === '/assignee') {
       elementId = '';
       action = 'clear';
     }
diff --git a/web_src/js/features/comp/ImagePaste.js b/web_src/js/features/comp/ImagePaste.js
index 13c1a17c25..79aeffa02b 100644
--- a/web_src/js/features/comp/ImagePaste.js
+++ b/web_src/js/features/comp/ImagePaste.js
@@ -65,7 +65,7 @@ export function initCompImagePaste($target) {
     for (const textarea of this.querySelectorAll('textarea')) {
       textarea.addEventListener('paste', async (e) => {
         for (const img of clipboardPastedImages(e)) {
-          const name = img.name.substr(0, img.name.lastIndexOf('.'));
+          const name = img.name.slice(0, img.name.lastIndexOf('.'));
           insertAtCursor(textarea, `![${name}]()`);
           const data = await uploadFile(img, uploadUrl);
           replaceAndKeepCursor(textarea, `![${name}]()`, `![${name}](/attachments/${data.uuid})`);
@@ -81,7 +81,7 @@ export function initEasyMDEImagePaste(easyMDE, dropzone, files) {
   const uploadUrl = dropzone.getAttribute('data-upload-url');
   easyMDE.codemirror.on('paste', async (_, e) => {
     for (const img of clipboardPastedImages(e)) {
-      const name = img.name.substr(0, img.name.lastIndexOf('.'));
+      const name = img.name.slice(0, img.name.lastIndexOf('.'));
       const data = await uploadFile(img, uploadUrl);
       const pos = easyMDE.codemirror.getCursor();
       easyMDE.codemirror.replaceRange(`![${name}](/attachments/${data.uuid})`, pos);
diff --git a/web_src/js/features/repo-code.js b/web_src/js/features/repo-code.js
index 82ab902ce1..a4b6e433a5 100644
--- a/web_src/js/features/repo-code.js
+++ b/web_src/js/features/repo-code.js
@@ -36,8 +36,8 @@ function selectRange($list, $select, $from) {
   };
 
   if ($from) {
-    let a = parseInt($select.attr('rel').substr(1));
-    let b = parseInt($from.attr('rel').substr(1));
+    let a = parseInt($select.attr('rel').slice(1));
+    let b = parseInt($from.attr('rel').slice(1));
     let c;
     if (a !== b) {
       if (a > b) {
diff --git a/web_src/js/features/repo-issue.js b/web_src/js/features/repo-issue.js
index 69911a1734..bdb75842f8 100644
--- a/web_src/js/features/repo-issue.js
+++ b/web_src/js/features/repo-issue.js
@@ -412,7 +412,7 @@ export function initRepoPullRequestReview() {
       // get the name of the parent id
       const groupID = commentDiv.closest('div[id^="code-comments-"]').attr('id');
       if (groupID && groupID.startsWith('code-comments-')) {
-        const id = groupID.substr(14);
+        const id = groupID.slice(14);
         $(`#show-outdated-${id}`).addClass('hide');
         $(`#code-comments-${id}`).removeClass('hide');
         $(`#code-preview-${id}`).removeClass('hide');
@@ -560,7 +560,7 @@ export function initRepoIssueWipToggle() {
     const updateUrl = toggleWip.getAttribute('data-update-url');
     await $.post(updateUrl, {
       _csrf: csrfToken,
-      title: title?.startsWith(wipPrefix) ? title.substr(wipPrefix.length).trim() : `${wipPrefix.trim()} ${title}`,
+      title: title?.startsWith(wipPrefix) ? title.slice(wipPrefix.length).trim() : `${wipPrefix.trim()} ${title}`,
     });
     window.location.reload();
   });
diff --git a/web_src/js/features/repo-projects.js b/web_src/js/features/repo-projects.js
index 21cb567456..3147626b51 100644
--- a/web_src/js/features/repo-projects.js
+++ b/web_src/js/features/repo-projects.js
@@ -171,9 +171,9 @@ export default function initRepoProject() {
 }
 
 function setLabelColor(label, color) {
-  const red = getRelativeColor(parseInt(color.substr(1, 2), 16));
-  const green = getRelativeColor(parseInt(color.substr(3, 2), 16));
-  const blue = getRelativeColor(parseInt(color.substr(5, 2), 16));
+  const red = getRelativeColor(parseInt(color.slice(1, 3), 16));
+  const green = getRelativeColor(parseInt(color.slice(3, 5), 16));
+  const blue = getRelativeColor(parseInt(color.slice(5, 7), 16));
   const luminance = 0.2126 * red + 0.7152 * green + 0.0722 * blue;
 
   if (luminance > 0.179) {