diff --git a/.changeset/lovely-bobcats-lie.md b/.changeset/lovely-bobcats-lie.md
new file mode 100644
index 0000000000..6c0522d28b
--- /dev/null
+++ b/.changeset/lovely-bobcats-lie.md
@@ -0,0 +1,5 @@
+---
+'graphiql': minor
+---
+
+allow reassign name of the tabs
diff --git a/packages/graphiql-react/src/ui/tabs.css b/packages/graphiql-react/src/ui/tabs.css
index 66cd5b7336..87f8e9996b 100644
--- a/packages/graphiql-react/src/ui/tabs.css
+++ b/packages/graphiql-react/src/ui/tabs.css
@@ -16,12 +16,34 @@
   min-width: 0;
 }
 
+.graphiql-tab-input {
+  all: unset;
+  width: 100%;
+  padding: var(--px-4) 28px var(--px-4) var(--px-8);
+  border-radius: var(--border-radius-8) var(--border-radius-8) 0 0;
+
+  &:focus {
+    outline: hsla(var(--color-neutral), var(--alpha-background-heavy)) auto 1px;
+  }
+
+  &[readonly] {
+    cursor: pointer;
+    /* remove selection when focusing */
+    &::selection {
+      user-select: none;
+    }
+  }
+}
+
+.graphiql-tab:has(input[readonly]) {
+  max-width: 140px;
+}
+
 .graphiql-tab {
   border-radius: var(--border-radius-8) var(--border-radius-8) 0 0;
   background: hsla(var(--color-neutral), var(--alpha-background-light));
   position: relative;
   display: flex;
-  max-width: 140px;
 
   /* disable shrinking while changing the operation name */
   &:not(:focus-within) {
diff --git a/packages/graphiql/src/components/GraphiQL.tsx b/packages/graphiql/src/components/GraphiQL.tsx
index 58d035e6e4..82ebad0602 100644
--- a/packages/graphiql/src/components/GraphiQL.tsx
+++ b/packages/graphiql/src/components/GraphiQL.tsx
@@ -19,6 +19,9 @@ import React, {
   Children,
   JSX,
   cloneElement,
+  MouseEvent,
+  FocusEvent,
+  ComponentProps,
 } from 'react';
 
 import {
@@ -240,6 +243,33 @@ const THEMES = ['light', 'dark', 'system'] as const;
 
 const TAB_CLASS_PREFIX = 'graphiql-session-tab-';
 
+const handleTabValueChange: ComponentProps<'input'>['onChange'] = event => {
+  const input = event.target;
+  // Should be at least 1 character wide, otherwise will throw DOMException
+  input.size = Math.max(1, input.value.length - 1);
+};
+
+const handleTabValueKeyDown: ComponentProps<'input'>['onKeyDown'] = event => {
+  if (event.key !== 'Enter' && event.key !== 'Escape') {
+    return;
+  }
+  const input = event.currentTarget;
+
+  if (!input.value) {
+    input.value = input.defaultValue;
+    // @ts-expect-error
+    handleTabValueChange(event);
+  }
+  input.blur();
+};
+
+const handleTabDoubleClickAndBlur = (
+  event: MouseEvent<HTMLInputElement> | FocusEvent<HTMLInputElement>,
+) => {
+  const input = event.currentTarget;
+  input.readOnly = event.type === 'blur';
+};
+
 export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
   const isHeadersEditorEnabled = props.isHeadersEditorEnabled ?? true;
   const editorContext = useEditorContext({ nonNull: true });
@@ -490,7 +520,7 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
     [confirmClose, editorContext, executionContext],
   );
 
-  const handleTabClick: MouseEventHandler<HTMLButtonElement> = useCallback(
+  const handleTabClick: MouseEventHandler<HTMLInputElement> = useCallback(
     event => {
       const index = Number(
         event.currentTarget.id.replace(TAB_CLASS_PREFIX, ''),
@@ -594,14 +624,25 @@ export function GraphiQLInterface(props: GraphiQLInterfaceProps) {
                     value={tab}
                     isActive={index === editorContext.activeTabIndex}
                   >
-                    <Tab.Button
+                    <input
+                      key={tab.title}
+                      className="graphiql-tab-input"
                       aria-controls="graphiql-session"
                       id={`graphiql-session-tab-${index}`}
                       title={tab.title}
+                      defaultValue={tab.title}
+                      size={Math.max(tab.title.length - 1, 1)}
+                      onChange={handleTabValueChange}
+                      onKeyDown={handleTabValueKeyDown}
+                      onDoubleClick={handleTabDoubleClickAndBlur}
+                      onBlur={handleTabDoubleClickAndBlur}
                       onClick={handleTabClick}
-                    >
-                      {tab.title}
-                    </Tab.Button>
+                      // Can be writable only after double click
+                      readOnly
+                      // Disable autocomplete for tab names
+                      autoComplete="off"
+                    />
+
                     {tabs.length > 1 && <Tab.Close onClick={handleTabClose} />}
                   </Tab>
                 ))}
diff --git a/packages/graphiql/vite.config.mts b/packages/graphiql/vite.config.mts
index f6f830074f..fef6ea0418 100644
--- a/packages/graphiql/vite.config.mts
+++ b/packages/graphiql/vite.config.mts
@@ -1,7 +1,6 @@
 import { defineConfig, PluginOption } from 'vite';
 import packageJSON from './package.json';
 import dts from 'vite-plugin-dts';
-import commonjs from 'vite-plugin-commonjs';
 
 const umdConfig = defineConfig({
   define: {
@@ -11,8 +10,6 @@ const umdConfig = defineConfig({
     'globalThis.process': 'true',
     'process.env.NODE_ENV': '"production"',
   },
-  // To bundle `const { createClient } = require('graphql-ws')` in `createWebsocketsFetcherFromUrl` function
-  plugins: [commonjs()],
   build: {
     minify: 'terser', // produce less bundle size
     sourcemap: true,