diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..3ce419a
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,2 @@
+HOSTNAME=localhost
+PORT=2056
\ No newline at end of file
diff --git a/index.ts b/index.ts
deleted file mode 100644
index e4b48b7..0000000
--- a/index.ts
+++ /dev/null
@@ -1,119 +0,0 @@
-import { file, gc, serve } from "bun";
-
-import Backend from "./src/back";
-
-import pkg from "./package.json";
-
-let heartrate = 0;
-let lanyard = {};
-
-require("node:fs/promises")
-	.rm("./dist", { recursive: true, force: true })
-	.catch(() => {
-		// ignore
-	});
-
-if (!Backend.development) {
-	await Backend.build();
-}
-
-const server = serve({
-	routes: {
-		"/": async (req: Bun.BunRequest, server: Bun.Server) => {
-			await Backend.postAnalytics(req, server);
-
-			if (Backend.development) {
-				await Backend.build();
-			}
-
-			return await Backend.Responses.file(file("./dist/index.html"));
-		},
-
-		"/assets/:file": async (req: Bun.BunRequest<"/assets/:file">) => {
-			return await Backend.Responses.file(file(`./dist/${req.params.file}`));
-		},
-
-		"/public/:file": async (req: Bun.BunRequest<"/public/:file">) => {
-			return await Backend.Responses.file(file(`./public/${req.params.file}`));
-		},
-
-		"/api/server": () => {
-			const string = JSON.stringify(process);
-			const data = JSON.parse(string);
-
-			// clear possibly data that could be sensitive
-			data.env = {};
-
-			data.availableMemory = process.availableMemory();
-			data.constrainedMemory = process.constrainedMemory();
-			data.cpuUsage = process.cpuUsage();
-			data.memoryUsage = process.memoryUsage();
-			data.uptime = process.uptime();
-			data.package = pkg;
-
-			return Backend.Responses.json({ data });
-		},
-		"/api/health": () => {
-			return Backend.Responses.ok();
-		},
-		"/api/ws": async (req, server) => {
-			if (server.upgrade(req)) {
-				return;
-			}
-
-			await Backend.postAnalytics(req, server);
-			return Response.redirect("/");
-		},
-		"/api/gc": async () => {
-			gc(true);
-
-			return Backend.Responses.ok();
-		},
-		"/api/headers": async (req) => {
-			return Backend.Responses.json({ ...req.headers.toJSON() });
-		},
-	},
-
-	fetch: async (request, server) => {
-		await Backend.postAnalytics(request, server);
-
-		return Response.redirect("/");
-	},
-
-	websocket: {
-		idleTimeout: 1,
-		open: async (ws) => {
-			ws.subscribe("lanyard");
-			ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
-
-			ws.subscribe("hyperate");
-			ws.send(
-				JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
-				true,
-			);
-		},
-		message: async (ws, message) => {
-			ws.send(JSON.stringify({ type: "echo", data: message }), true);
-		},
-	},
-	development: Backend.development,
-	port: 2056,
-});
-
-new Backend.Sockets.Hyperate((data) => {
-	heartrate = data;
-	server.publish(
-		"hyperate",
-		JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
-		true,
-	);
-});
-
-new Backend.Sockets.Lanyard((data) => {
-	lanyard = data;
-	server.publish(
-		"lanyard",
-		JSON.stringify({ type: "lanyard", data: lanyard }),
-		true,
-	);
-});
diff --git a/package.json b/package.json
index 8cc2293..10fdfd5 100644
--- a/package.json
+++ b/package.json
@@ -2,8 +2,8 @@
 	"name": "ipv4.army",
 	"module": "index.ts",
 	"scripts": {
-		"dev": "NODE_ENV=development bun run --hot . --watch",
-		"start": "bun run .",
+		"dev": "NODE_ENV=development bun run --hot src/index.ts",
+		"start": "bun run src/index.ts",
 		"lint": "bunx biome ci . --verbose",
 		"lint:fix": "bunx biome check --fix"
 	},
diff --git a/src/back/Sockets/Lanyard.ts b/src/back/Sockets/Lanyard.ts
index 04f9b9d..7d92430 100644
--- a/src/back/Sockets/Lanyard.ts
+++ b/src/back/Sockets/Lanyard.ts
@@ -3,9 +3,9 @@ import ReconnectingWebSocket from "reconnecting-websocket";
 export default class {
 	private _socket: ReconnectingWebSocket;
 	private _keepAlive: NodeJS.Timeout | null;
-	private _callback: (data: { [key: string]: string }) => void;
+	private _callback: (data: LanyardData) => void;
 
-	constructor(callback: (data: { [key: string]: string }) => void) {
+	constructor(callback: (data: LanyardData) => void) {
 		this._socket = new ReconnectingWebSocket(
 			"wss://lanyard.creations.works/socket",
 		);
diff --git a/src/front/App.tsx b/src/front/App.tsx
index 40dd719..7e0a8cb 100644
--- a/src/front/App.tsx
+++ b/src/front/App.tsx
@@ -1,27 +1,145 @@
 import Hyperate from "./components/Hyperate";
 import Lanyard from "./components/Lanyard";
 
+let latestLanyard: LanyardData | null = null;
+
+window.addEventListener("lanyard-update", (e) => {
+	latestLanyard = (e as CustomEvent<LanyardData>).detail;
+});
+
 export default () => {
-	return (
-		<div class="app">
-			<p>seth&gt; cat ./about.txt</p>
-			<p>
-				A Dedicated Backend Developer,
-				<br />
-				with a passion for high-fidelity audio,
-				<br />
-				gaming, and web development.
-			</p>
+	const container = document.createElement("div");
+	container.className = "app terminal";
 
-			<p>seth&gt; curl /tmp/discord-ipc</p>
-			<p>
-				<Lanyard />
-			</p>
+	const renderElement = (content: string | Node) => {
+		const p = document.createElement("p");
+		if (typeof content === "string") {
+			p.textContent = content;
+		} else {
+			p.appendChild(content);
+		}
+		return p;
+	};
 
-			<p>seth&gt; cat /tmp/heartrate</p>
-			<p>
-				<Hyperate />
-			</p>
-		</div>
-	);
+	const prompt = "[seth@ipv4 ~]$";
+
+	const staticLines: (string | (() => Node))[] = [
+		`${prompt} cat ./about.txt`,
+		() =>
+			document
+				.createRange()
+				.createContextualFragment(
+					"A Dedicated Backend Developer,<br />with a passion for high-fidelity audio,<br />gaming, and web development.",
+				),
+		`${prompt} cat /tmp/discord-ipc`,
+		() => Lanyard(),
+		`${prompt} cat /tmp/heartrate`,
+		() => Hyperate(),
+	];
+
+	const renderStatic = () => {
+		for (const line of staticLines) {
+			const content = typeof line === "function" ? line() : line;
+			container.appendChild(renderElement(content));
+		}
+	};
+
+	renderStatic();
+
+	const lanyardInstance = Lanyard();
+	const files: Record<string, () => Node> = {
+		"./about.txt": () =>
+			document
+				.createRange()
+				.createContextualFragment(
+					"A Dedicated Backend Developer,<br />with a passion for high-fidelity audio,<br />gaming, and web development.",
+				),
+		"/tmp/discord-ipc": () => lanyardInstance,
+		"/tmp/heartrate": () => Hyperate(),
+	};	
+
+	const history: string[] = [];
+	let historyIndex = -1;
+
+	const inputBox = document.createElement("input");
+	inputBox.className = "terminal-input";
+	inputBox.autofocus = true;
+
+	const inputLine = document.createElement("div");
+	inputLine.className = "terminal-line";
+
+	const promptSpan = document.createElement("span");
+	promptSpan.textContent = `${prompt} `;
+
+	inputLine.appendChild(promptSpan);
+	inputLine.appendChild(inputBox);
+	container.appendChild(inputLine);
+
+	const appendLine = (line: string | Node) => {
+		container.insertBefore(renderElement(line), inputLine);
+	};
+
+	inputBox.addEventListener("keydown", (e) => {
+		if (e.key === "Enter") {
+			const cmd = inputBox.value.trim();
+			if (!cmd) return;
+
+			history.push(cmd);
+			historyIndex = history.length;
+
+			appendLine(`${prompt} ${cmd}`);
+
+			let out: string | Node;
+
+			if (cmd.startsWith("cat ")) {
+				const file = cmd.slice(4).trim();
+				out = files[file]?.() ?? `cat: ${file}: No such file`;
+			} else if (cmd === "ls") {
+				out = Object.keys(files)
+					.filter((f) => f.startsWith("./"))
+					.map((f) => f.slice(2))
+					.join("\n");
+			} else if (cmd.startsWith("ls ")) {
+				const dir = cmd.slice(3).trim();
+				if (dir === "/tmp") {
+					out = Object.keys(files)
+						.filter((f) => f.startsWith("/tmp/"))
+						.map((f) => f.slice("/tmp/".length))
+						.join("\n");
+				} else {
+					out = `ls: cannot access '${dir}': No such file or directory`;
+				}
+			} else if (cmd === "help") {
+				out = [
+					"Available commands:",
+					"  cat [file]     View contents of a file",
+					"  ls             List files in current directory",
+					"  ls /tmp        List files in /tmp directory",
+					"  help           Show this message",
+				].join("\n");
+			} else {
+				out = `bash: ${cmd}: command not found`;
+			}			
+
+			appendLine(out);
+			inputBox.value = "";
+		} else if (e.key === "ArrowUp") {
+			if (historyIndex > 0) {
+				historyIndex--;
+				inputBox.value = history[historyIndex] || "";
+			}
+			e.preventDefault();
+		} else if (e.key === "ArrowDown") {
+			if (historyIndex < history.length - 1) {
+				historyIndex++;
+				inputBox.value = history[historyIndex] || "";
+			} else {
+				historyIndex = history.length;
+				inputBox.value = "";
+			}
+			e.preventDefault();
+		}
+	});
+
+	return container;
 };
diff --git a/src/front/Socket.ts b/src/front/Socket.ts
index 3c271bf..334effc 100644
--- a/src/front/Socket.ts
+++ b/src/front/Socket.ts
@@ -39,8 +39,11 @@ class Socket extends EventTarget {
 		}, 30 * 1000);
 	}
 
-	emitLanyard(lanyard: object) {
+	emitLanyard(lanyard: LanyardData) {
 		this.dispatchEvent(new CustomEvent("lanyard", { detail: lanyard }));
+		window.dispatchEvent(
+			new CustomEvent("lanyard-update", { detail: lanyard }),
+		);
 	}
 	emitHyperate(heartRate: number) {
 		this.dispatchEvent(new CustomEvent("hyperate", { detail: heartRate }));
diff --git a/src/front/components/Lanyard/index.tsx b/src/front/components/Lanyard/index.tsx
index aee6527..9b58d6a 100644
--- a/src/front/components/Lanyard/index.tsx
+++ b/src/front/components/Lanyard/index.tsx
@@ -1,22 +1,22 @@
-import { highlightAll } from "@speed-highlight/core";
+import { highlightElement } from "@speed-highlight/core";
 import { createRef } from "tsx-dom";
-
 import socket from "../../Socket";
 
-const statusTypes: { [key: string]: string } = {
+const statusTypes = {
 	online: "rgb(0, 150, 0)",
 	idle: "rgb(150, 150, 0)",
 	dnd: "rgb(150, 0, 0)",
 	offline: "rgb(150, 150, 150)",
 };
 
-const gradientTypes: { [key: string]: string } = {
+const gradientTypes = {
 	online: "rgba(0, 150, 0, 0.1)",
 	idle: "rgba(150, 150, 0, 0.1)",
 	dnd: "rgba(150, 0, 0, 0.1)",
 	offline: "rgba(150, 150, 150, 0.1)",
 };
-const activityTypes: { [key: number]: string } = {
+
+const activityTypes: Record<number, string> = {
 	0: "Playing",
 	1: "Streaming",
 	2: "Listening to",
@@ -25,43 +25,37 @@ const activityTypes: { [key: number]: string } = {
 	5: "Competing in",
 };
 
-const stringify = (data: { [key: string]: string }) => {
-	return JSON.stringify(data, null, 2);
-};
-
 export default () => {
-	const code = createRef<HTMLDivElement>();
+	const container = createRef<HTMLDivElement>();
 
 	socket.addEventListener("lanyard", (event: Event) => {
-		const lanyard = (event as CustomEvent).detail;
+		const lanyard = (event as CustomEvent<LanyardData>).detail;
+
 		document.body.style = `--status-color: ${statusTypes[lanyard.discord_status]}; --gradient-color: ${gradientTypes[lanyard.discord_status]};`;
-		if (code.current) {
-			code.current.innerHTML = stringify({
-				status: lanyard.discord_status,
-				activities: lanyard.activities.map(
-					(act: {
-						type: number;
-						name: string;
-						details: string;
-						state: string;
-					}) => {
-						return [
-							...new Set([
-								activityTypes[act.type],
-								act.name,
-								act.details,
-								act.state,
-							]),
-						].filter((n) => n);
-					},
-				),
-			});
+
+		if (container.current) {
+			container.current.className = "shj-lang-json";
+			container.current.textContent = JSON.stringify(
+				{
+					status: lanyard.discord_status,
+					activities: lanyard.activities.map((act) => {
+						const type = activityTypes[act.type];
+						const parts = [type];
+						if (act.name !== type) parts.push(act.name);
+						if (act.details) parts.push(act.details);
+						if (act.state) parts.push(act.state);
+						return parts;
+					}),
+				},
+				null,
+				2
+			);
+			highlightElement(container.current);
 		}
-		highlightAll();
 	});
 
 	return (
-		<div class="shj-lang-json" ref={code}>
+		<div class="shj-lang-json" ref={container}>
 			{"{}"}
 		</div>
 	);
diff --git a/src/front/index.css b/src/front/index.css
index 1b5386d..f52e3e0 100644
--- a/src/front/index.css
+++ b/src/front/index.css
@@ -1,5 +1,4 @@
 @import "../../node_modules/@speed-highlight/core/dist/themes/dark.css";
-
 @import "./App.css";
 
 html,
@@ -21,4 +20,47 @@ body {
 		rgba(0, 0, 0, 1) 100%
 	);
 	display: flex;
+	height: 100vh;
+	width: 100vw;
+	overflow: hidden;
+}
+
+p {
+	margin: 0;
+	padding: 0;
+	line-height: 1.4em;
+}
+
+.terminal {
+	white-space: pre-wrap;
+	font-family: monospace;
+	width: 100vw;
+	height: 100vh;
+	overflow-y: auto;
+	display: flex;
+	flex-direction: column;
+	box-sizing: border-box;
+
+	gap: 0.4em;
+}
+
+.terminal-input {
+	background: transparent;
+	border: none;
+	color: inherit;
+	font: inherit;
+	outline: none;
+	display: inline-block;
+	width: 100%;
+}
+
+.terminal-line {
+	display: flex;
+	align-items: baseline;
+	flex-direction: row;
+	width: 100%;
+}
+
+.terminal-line > span {
+	white-space: pre;
 }
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..65da033
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,105 @@
+import fs from "node:fs/promises";
+import { file, gc, serve } from "bun";
+import pkg from "../package.json";
+import Backend from "./back";
+
+let heartrate = 0;
+let lanyard: LanyardData = {
+	discord_status: "online",
+	activities: [],
+};
+
+await fs.rm("./dist", { recursive: true, force: true }).catch(() => {});
+
+if (!Backend.development) {
+	await Backend.build();
+}
+
+const server = serve({
+	port: process.env.PORT || 3000,
+	hostname: process.env.HOSTNAME || "localhost",
+	development: Backend.development,
+
+	routes: {
+		"/": async (req, server) => {
+			await Backend.postAnalytics(req, server);
+			if (Backend.development) await Backend.build();
+			return Backend.Responses.file(file("./dist/index.html"));
+		},
+
+		"/assets/:file": async (req) =>
+			Backend.Responses.file(file(`./dist/${req.params.file}`)),
+
+		"/public/:file": async (req) =>
+			Backend.Responses.file(file(`./public/${req.params.file}`)),
+
+		"/api/server": () => {
+			const safeProcess = JSON.parse(JSON.stringify(process));
+			safeProcess.env = {};
+			safeProcess.availableMemory = process.availableMemory();
+			safeProcess.constrainedMemory = process.constrainedMemory();
+			safeProcess.cpuUsage = process.cpuUsage();
+			safeProcess.memoryUsage = process.memoryUsage();
+			safeProcess.uptime = process.uptime();
+			safeProcess.package = pkg;
+
+			return Backend.Responses.json({ data: safeProcess });
+		},
+
+		"/api/health": () => Backend.Responses.ok(),
+
+		"/api/ws": async (req, server) => {
+			if (!server.upgrade(req)) {
+				await Backend.postAnalytics(req, server);
+				return Response.redirect("/");
+			}
+		},
+
+		"/api/gc": async () => {
+			gc(true);
+			return Backend.Responses.ok();
+		},
+
+		"/api/headers": (req) => Backend.Responses.json(req.headers.toJSON()),
+	},
+
+	fetch: async (req, server) => {
+		await Backend.postAnalytics(req, server);
+		return Response.redirect("/");
+	},
+
+	websocket: {
+		idleTimeout: 1,
+		open: (ws) => {
+			ws.subscribe("lanyard");
+			ws.send(JSON.stringify({ type: "lanyard", data: lanyard }), true);
+
+			ws.subscribe("hyperate");
+			ws.send(
+				JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
+				true,
+			);
+		},
+		message: (ws, msg) => {
+			ws.send(JSON.stringify({ type: "echo", data: msg }), true);
+		},
+	},
+});
+
+new Backend.Sockets.Hyperate((data) => {
+	heartrate = data;
+	server.publish(
+		"hyperate",
+		JSON.stringify({ type: "hyperate", data: { hr: heartrate } }),
+		true,
+	);
+});
+
+new Backend.Sockets.Lanyard((data) => {
+	lanyard = data;
+	server.publish(
+		"lanyard",
+		JSON.stringify({ type: "lanyard", data: lanyard }),
+		true,
+	);
+});
diff --git a/tsconfig.json b/tsconfig.json
index ab77b3d..a7c98f5 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -21,6 +21,7 @@
 		// Some stricter flags (disabled by default)
 		"noUnusedLocals": false,
 		"noUnusedParameters": false,
-		"noPropertyAccessFromIndexSignature": false
+		"noPropertyAccessFromIndexSignature": false,
+		"typeRoots": ["./types"]
 	}
 }
diff --git a/types/lanyard.d.ts b/types/lanyard.d.ts
new file mode 100644
index 0000000..d0f92b0
--- /dev/null
+++ b/types/lanyard.d.ts
@@ -0,0 +1,13 @@
+type LanyardActivity = {
+	type: number;
+	name: string;
+	details?: string;
+	state?: string;
+	[key: string]: unknown;
+};
+
+type LanyardData = {
+	discord_status: "online" | "idle" | "dnd" | "offline";
+	activities: LanyardActivity[];
+	[key: string]: unknown;
+};