diff --git a/client/web/src/components/app.tsx b/client/web/src/components/app.tsx
index c9bf441be..b90f993b7 100644
--- a/client/web/src/components/app.tsx
+++ b/client/web/src/components/app.tsx
@@ -3,7 +3,6 @@ import React, { useEffect } from "react"
import LoginToggle from "src/components/login-toggle"
import DeviceDetailsView from "src/components/views/device-details-view"
import HomeView from "src/components/views/home-view"
-import LegacyClientView from "src/components/views/legacy-client-view"
import LoginClientView from "src/components/views/login-client-view"
import SSHView from "src/components/views/ssh-view"
import { UpdatingView } from "src/components/views/updating-view"
@@ -46,17 +45,6 @@ function WebClient({
data={data}
onLoginClick={() => updateNode({ Reauthenticate: true })}
/>
- ) : data.DebugMode !== "full" && data.DebugMode !== "login" ? (
- // Render legacy client interface.
- <>
-
- {/* TODO: add license to new client */}
-
- >
) : (
// Otherwise render the new web client.
<>
diff --git a/client/web/src/components/views/legacy-client-view.tsx b/client/web/src/components/views/legacy-client-view.tsx
deleted file mode 100644
index 2daa8a494..000000000
--- a/client/web/src/components/views/legacy-client-view.tsx
+++ /dev/null
@@ -1,232 +0,0 @@
-import cx from "classnames"
-import React from "react"
-import { apiFetch } from "src/api"
-import { NodeData, NodeUpdate } from "src/hooks/node-data"
-
-// TODO(tailscale/corp#13775): legacy.tsx contains a set of components
-// that (crudely) implement the pre-2023 web client. These are implemented
-// purely to ease migration to the new React-based web client, and will
-// eventually be completely removed.
-
-export default function LegacyClientView({
- data,
- refreshData,
- updateNode,
-}: {
- data: NodeData
- refreshData: () => void
- updateNode: (update: NodeUpdate) => void
-}) {
- return (
-
-
-
- {data.Status === "NeedsMachineAuth" ? (
-
- This device is authorized, but needs approval from a network admin
- before it can connect to the network.
-
- ) : (
- <>
-
-
- You are connected! Access this device over Tailscale using the
- device name or IP address above.
-
-
-
- >
- )}
-
- )
-}
-
-export function Header({
- data,
- refreshData,
- updateNode,
-}: {
- data: NodeData
- refreshData: () => void
- updateNode: (update: NodeUpdate) => void
-}) {
- return (
-
- )
-}
-
-export function IP(props: { data: NodeData }) {
- const { data } = props
-
- if (!data.IP) {
- return null
- }
-
- return (
- <>
-
-
-
-
- {data.DeviceName || "Your device"}
-
-
-
{data.IP}
-
-
- Debug info: Tailscale {data.IPNVersion}, tun={data.TUNMode.toString()}
- {data.IsSynology && (
- <>
- , DSM{data.DSMVersion}
- {data.TUNMode || (
- <>
- {" "}
- (
-
- outgoing access not configured
-
- )
- >
- )}
- >
- )}
-
- >
- )
-}