Blocks
A block is an arrangement of components, not new markup: the parts are the ones documented under Components, and restyling one is still a matter of overriding a token. Install a block and you get every component it is built from.
Chat window
A whole channel view: header, scrolling message list and composer, composed from the registry.
pnpm dlx newtui@latest add chat-windownpx newtui@latest add chat-windowyarn dlx newtui@latest add chat-windowbunx newtui@latest add chat-windowimport { ChatWindow } from "@/registry/bases/newt/blocks/chat-window/chat-window"
/* Placeholder names and text: no real account, and no Discord asset. */
const MESSAGES = [
{
id: "1",
author: "username",
initials: "U",
body: "Welcome to the channel.",
sentAt: "2026-09-07T14:23:00.000Z",
displayTime: "Today at 14:23",
},
{
id: "2",
author: "someone",
initials: "S",
body: "The deploy finished — logs look clean.",
sentAt: "2026-09-07T14:25:00.000Z",
displayTime: "Today at 14:25",
},
] as const
export default function ChatWindowDemo() {
return (
<ChatWindow
className="w-full max-w-lg"
channelName="general"
topic="Say hello and tell us what you are building."
messages={MESSAGES}
/>
)
}<script setup lang="ts">
import { ChatWindow } from "~~/registry/bases/newt/blocks/chat-window"
/* Placeholder names and text: no real account, and no Discord asset. */
const MESSAGES = [
{
id: "1",
author: "username",
initials: "U",
body: "Welcome to the channel.",
sentAt: "2026-09-07T14:23:00.000Z",
displayTime: "Today at 14:23",
},
{
id: "2",
author: "someone",
initials: "S",
body: "The deploy finished — logs look clean.",
sentAt: "2026-09-07T14:25:00.000Z",
displayTime: "Today at 14:25",
},
]
</script>
<template>
<ChatWindow
class="w-full max-w-lg"
channel-name="general"
topic="Say hello and tell us what you are building."
:messages="MESSAGES"
/>
</template>Server sidebar
The column beside a channel: the server banner, the voice channel and the grouped member list.
pnpm dlx newtui@latest add server-sidebarnpx newtui@latest add server-sidebaryarn dlx newtui@latest add server-sidebarbunx newtui@latest add server-sidebarimport { ServerSidebar } from "@/registry/bases/newt/blocks/server-sidebar/server-sidebar"
/* Placeholder names: no real account, and no Discord asset. */
const MEMBERS = [
{
id: "1",
name: "alex",
initials: "A",
status: "online",
group: "Moderators",
},
{ id: "2", name: "sam", initials: "S", status: "idle", group: "Online" },
{ id: "3", name: "robin", initials: "R", status: "dnd", group: "Online" },
{ id: "4", name: "kit", initials: "K", status: "offline", group: "Offline" },
] as const
export default function ServerSidebarDemo() {
return (
<ServerSidebar
className="w-64"
serverName="Build Club"
voiceChannel={{ name: "General voice", members: ["alex", "sam"] }}
members={MEMBERS}
/>
)
}<script setup lang="ts">
import { ServerSidebar } from "~~/registry/bases/newt/blocks/server-sidebar"
import type { SidebarMember } from "~~/registry/bases/newt/blocks/server-sidebar"
/* Placeholder names: no real account, and no Discord asset. */
const MEMBERS: SidebarMember[] = [
{
id: "1",
name: "alex",
initials: "A",
status: "online",
group: "Moderators",
},
{ id: "2", name: "sam", initials: "S", status: "idle", group: "Online" },
{ id: "3", name: "robin", initials: "R", status: "dnd", group: "Online" },
{ id: "4", name: "kit", initials: "K", status: "offline", group: "Offline" },
]
</script>
<template>
<ServerSidebar
class="w-64"
server-name="Build Club"
:voice-channel="{ name: 'General voice', members: ['alex', 'sam'] }"
:members="MEMBERS"
/>
</template>Command panel
A command browser with a selectable suggestion list and a detailed option card.
pnpm dlx newtui@latest add command-panelnpx newtui@latest add command-panelyarn dlx newtui@latest add command-panelbunx newtui@latest add command-panelimport { CommandPanel } from "@/registry/bases/newt/blocks/command-panel/command-panel"
const COMMANDS = [
{
id: "poll",
name: "poll create",
description: "Create a poll for the current channel.",
appLabel: "Community",
options: [
{
name: "question",
type: "STRING",
required: true,
description: "The question people will answer.",
},
{
name: "duration",
type: "INTEGER",
description: "How many hours the poll stays open.",
},
],
},
{
id: "remind",
name: "remind",
description: "Schedule a reminder in this channel.",
appLabel: "Utilities",
options: [
{ name: "when", type: "STRING", required: true },
{ name: "message", type: "STRING", required: true },
],
},
{
id: "topic",
name: "topic suggest",
description: "Suggest a conversation prompt.",
appLabel: "Community",
},
] as const
export default function CommandPanelDemo() {
return <CommandPanel commands={COMMANDS} defaultSelectedId="poll" />
}<script setup lang="ts">
import { CommandPanel } from "~~/registry/bases/newt/blocks/command-panel"
import type { CommandPanelCommand } from "~~/registry/bases/newt/blocks/command-panel"
const COMMANDS: readonly CommandPanelCommand[] = [
{
id: "poll",
name: "poll create",
description: "Create a poll for the current channel.",
appLabel: "Community",
options: [
{
name: "question",
type: "STRING",
required: true,
description: "The question people will answer.",
},
{
name: "duration",
type: "INTEGER",
description: "How many hours the poll stays open.",
},
],
},
{
id: "remind",
name: "remind",
description: "Schedule a reminder in this channel.",
appLabel: "Utilities",
options: [
{ name: "when", type: "STRING", required: true },
{ name: "message", type: "STRING", required: true },
],
},
{
id: "topic",
name: "topic suggest",
description: "Suggest a conversation prompt.",
appLabel: "Community",
},
]
</script>
<template>
<CommandPanel :commands="COMMANDS" default-selected-id="poll" />
</template>