diff --git a/templates/index.ts b/templates/index.ts
index f1b5b2ef561d0bc00db2a941d1b8733b1b59e9e9..7fb46e45c624d8f232559ad91d020d1777fd6236 100644
--- a/templates/index.ts
+++ b/templates/index.ts
@@ -84,13 +84,6 @@ export const installTemplate = async ({
       parents: true,
       cwd: uiPath,
     });
-    const chatSectionFile = path.join(root, componentsPath, "chat-section.tsx");
-    const chatSectionFileContent = await fs.readFile(chatSectionFile, "utf8");
-    const newContent = chatSectionFileContent.replace(
-      /^import { ChatInput, ChatMessages, Message }.*$/m,
-      'import { ChatInput, ChatMessages, Message } from "./ui/chat"\n',
-    );
-    await fs.writeFile(chatSectionFile, newContent);
   }
 
   /**
@@ -116,7 +109,7 @@ export const installTemplate = async ({
     );
     // remove the default api folder
     const apiPath = path.join(root, "app", "api");
-    await fs.rmdir(apiPath, { recursive: true });
+    await fs.rm(apiPath, { recursive: true });
     // modify the dev script to use the custom api path
     packageJson.scripts = {
       ...packageJson.scripts,
diff --git a/templates/types/simple/nextjs/app/components/chat-section.tsx b/templates/types/simple/nextjs/app/components/chat-section.tsx
index 70740429b763214291a48963f2578756664ec05a..246d46e08caca8b09be62c195b9dfb3af4a81718 100644
--- a/templates/types/simple/nextjs/app/components/chat-section.tsx
+++ b/templates/types/simple/nextjs/app/components/chat-section.tsx
@@ -2,7 +2,7 @@
 
 import { nanoid } from "nanoid";
 import { useState } from "react";
-import { ChatInput, ChatMessages, Message } from "../../../../../ui/html/chat";
+import { ChatInput, ChatMessages, Message } from "./ui/chat";
 
 export default function ChatSection() {
   const [messages, setMessages] = useState<Message[]>([]);
diff --git a/templates/components/ui/html/chat/chat-avatar.tsx b/templates/types/simple/nextjs/app/components/ui/chat/chat-avatar.tsx
similarity index 100%
rename from templates/components/ui/html/chat/chat-avatar.tsx
rename to templates/types/simple/nextjs/app/components/ui/chat/chat-avatar.tsx
diff --git a/templates/components/ui/html/chat/chat-input.tsx b/templates/types/simple/nextjs/app/components/ui/chat/chat-input.tsx
similarity index 100%
rename from templates/components/ui/html/chat/chat-input.tsx
rename to templates/types/simple/nextjs/app/components/ui/chat/chat-input.tsx
diff --git a/templates/components/ui/html/chat/chat-item.tsx b/templates/types/simple/nextjs/app/components/ui/chat/chat-item.tsx
similarity index 100%
rename from templates/components/ui/html/chat/chat-item.tsx
rename to templates/types/simple/nextjs/app/components/ui/chat/chat-item.tsx
diff --git a/templates/components/ui/html/chat/chat-messages.tsx b/templates/types/simple/nextjs/app/components/ui/chat/chat-messages.tsx
similarity index 100%
rename from templates/components/ui/html/chat/chat-messages.tsx
rename to templates/types/simple/nextjs/app/components/ui/chat/chat-messages.tsx
diff --git a/templates/components/ui/html/chat/index.ts b/templates/types/simple/nextjs/app/components/ui/chat/index.ts
similarity index 100%
rename from templates/components/ui/html/chat/index.ts
rename to templates/types/simple/nextjs/app/components/ui/chat/index.ts
diff --git a/templates/types/streaming/nextjs/app/components/chat-section.tsx b/templates/types/streaming/nextjs/app/components/chat-section.tsx
index a36d2f2067c9a3332dfdf2d0e827d5b9492d767d..fd771fb3dd5221e3c63259ffcf154691cd13190e 100644
--- a/templates/types/streaming/nextjs/app/components/chat-section.tsx
+++ b/templates/types/streaming/nextjs/app/components/chat-section.tsx
@@ -1,7 +1,7 @@
 "use client";
 
 import { useChat } from "ai/react";
-import { ChatInput, ChatMessages, Message } from "../../../../../ui/html/chat";
+import { ChatInput, ChatMessages } from "./ui/chat";
 
 export default function ChatSection() {
   const { messages, input, isLoading, handleSubmit, handleInputChange } =
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..cd241104e4ef210c728aec47a1ab8b0161ad6538
--- /dev/null
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx
@@ -0,0 +1,34 @@
+"use client";
+
+import Image from "next/image";
+import { Message } from "./chat-messages";
+
+export default function ChatAvatar(message: Message) {
+  if (message.role === "user") {
+    return (
+      <div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border shadow bg-background">
+        <svg
+          xmlns="http://www.w3.org/2000/svg"
+          viewBox="0 0 256 256"
+          fill="currentColor"
+          className="h-4 w-4"
+        >
+          <path d="M230.92 212c-15.23-26.33-38.7-45.21-66.09-54.16a72 72 0 1 0-73.66 0c-27.39 8.94-50.86 27.82-66.09 54.16a8 8 0 1 0 13.85 8c18.84-32.56 52.14-52 89.07-52s70.23 19.44 89.07 52a8 8 0 1 0 13.85-8ZM72 96a56 56 0 1 1 56 56 56.06 56.06 0 0 1-56-56Z"></path>
+        </svg>
+      </div>
+    );
+  }
+
+  return (
+    <div className="flex h-8 w-8 shrink-0 select-none items-center justify-center rounded-md border  bg-black text-white">
+      <Image
+        className="rounded-md"
+        src="/llama.png"
+        alt="Llama Logo"
+        width={24}
+        height={24}
+        priority
+      />
+    </div>
+  );
+}
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..3eb979b02735943f3f11290c78b84f0e37709438
--- /dev/null
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
@@ -0,0 +1,42 @@
+"use client";
+
+export interface ChatInputProps {
+  /** The current value of the input */
+  input?: string;
+  /** An input/textarea-ready onChange handler to control the value of the input */
+  handleInputChange?: (
+    e:
+      | React.ChangeEvent<HTMLInputElement>
+      | React.ChangeEvent<HTMLTextAreaElement>,
+  ) => void;
+  /** Form submission handler to automatically reset input and append a user message  */
+  handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void;
+  isLoading: boolean;
+}
+
+export default function ChatInput(props: ChatInputProps) {
+  return (
+    <>
+      <form
+        onSubmit={props.handleSubmit}
+        className="flex items-start justify-between w-full max-w-5xl p-4 bg-white rounded-xl shadow-xl gap-4"
+      >
+        <input
+          autoFocus
+          name="message"
+          placeholder="Type a message"
+          className="w-full p-4 rounded-xl shadow-inner flex-1"
+          value={props.input}
+          onChange={props.handleInputChange}
+        />
+        <button
+          disabled={props.isLoading}
+          type="submit"
+          className="p-4 text-white rounded-xl shadow-xl bg-gradient-to-r from-cyan-500 to-sky-500 disabled:opacity-50 disabled:cursor-not-allowed"
+        >
+          Send message
+        </button>
+      </form>
+    </>
+  );
+}
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-item.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-item.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..2244f729a8ba668121ab5ec0842963d22153ef92
--- /dev/null
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-item.tsx
@@ -0,0 +1,13 @@
+"use client";
+
+import ChatAvatar from "./chat-avatar";
+import { Message } from "./chat-messages";
+
+export default function ChatItem(message: Message) {
+  return (
+    <div className="flex items-start gap-4 pt-5">
+      <ChatAvatar {...message} />
+      <p className="break-words">{message.content}</p>
+    </div>
+  );
+}
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..65eacabbfb1b7bc99950b43e7fd07ba56b3ecdb0
--- /dev/null
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
@@ -0,0 +1,38 @@
+"use client";
+
+import { useEffect, useRef } from "react";
+import ChatItem from "./chat-item";
+
+export interface Message {
+  id: string;
+  content: string;
+  role: string;
+}
+
+export default function ChatMessages({ messages }: { messages: Message[] }) {
+  const scrollableChatContainerRef = useRef<HTMLDivElement>(null);
+
+  const scrollToBottom = () => {
+    if (scrollableChatContainerRef.current) {
+      scrollableChatContainerRef.current.scrollTop =
+        scrollableChatContainerRef.current.scrollHeight;
+    }
+  };
+
+  useEffect(() => {
+    scrollToBottom();
+  }, [messages.length]);
+
+  return (
+    <div className="w-full max-w-5xl p-4 bg-white rounded-xl shadow-xl">
+      <div
+        className="flex flex-col gap-5 divide-y h-[50vh] overflow-auto"
+        ref={scrollableChatContainerRef}
+      >
+        {messages.map((m: Message) => (
+          <ChatItem key={m.id} {...m} />
+        ))}
+      </div>
+    </div>
+  );
+}
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/index.ts b/templates/types/streaming/nextjs/app/components/ui/chat/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4ccc54926fbd450313f952747bc1ea720100f2df
--- /dev/null
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/index.ts
@@ -0,0 +1,6 @@
+import ChatInput from "./chat-input";
+import ChatMessages from "./chat-messages";
+
+export type { ChatInputProps } from "./chat-input";
+export type { Message } from "./chat-messages";
+export { ChatMessages, ChatInput };