diff --git a/.changeset/chat-layout.md b/.changeset/chat-layout.md
new file mode 100644
index 0000000000..0d93a9f971
--- /dev/null
+++ b/.changeset/chat-layout.md
@@ -0,0 +1,5 @@
+---
+'@lg-chat/chat-layout': minor
+---
+
+Initial release of `ChatLayout`
diff --git a/README.md b/README.md
index a92fe7cc8f..255067d4e1 100644
--- a/README.md
+++ b/README.md
@@ -149,6 +149,7 @@ import Button from '@leafygreen-ui/button';
| [@lg-charts/legend](./charts/legend) | [](https://www.npmjs.com/package/@lg-charts/legend) |  | [Live Example](http://mongodb.design/component/legend/live-example) |
| [@lg-charts/series-provider](./charts/series-provider) | [](https://www.npmjs.com/package/@lg-charts/series-provider) |  | [Live Example](http://mongodb.design/component/series-provider/live-example) |
| [@lg-chat/avatar](./chat/avatar) | [](https://www.npmjs.com/package/@lg-chat/avatar) |  | [Live Example](http://mongodb.design/component/avatar/live-example) |
+| [@lg-chat/chat-layout](./chat/chat-layout) | [](https://www.npmjs.com/package/@lg-chat/chat-layout) |  | [Live Example](http://mongodb.design/component/chat-layout/live-example) |
| [@lg-chat/chat-window](./chat/chat-window) | [](https://www.npmjs.com/package/@lg-chat/chat-window) |  | [Live Example](http://mongodb.design/component/chat-window/live-example) |
| [@lg-chat/fixed-chat-window](./chat/fixed-chat-window) | [](https://www.npmjs.com/package/@lg-chat/fixed-chat-window) |  | [Live Example](http://mongodb.design/component/fixed-chat-window/live-example) |
| [@lg-chat/input-bar](./chat/input-bar) | [](https://www.npmjs.com/package/@lg-chat/input-bar) |  | [Live Example](http://mongodb.design/component/input-bar/live-example) |
diff --git a/chat/chat-layout/README.md b/chat/chat-layout/README.md
new file mode 100644
index 0000000000..d1c999a6b7
--- /dev/null
+++ b/chat/chat-layout/README.md
@@ -0,0 +1,128 @@
+# Chat Layout
+
+
+
+#### [View on MongoDB.design](https://www.mongodb.design/component/chat-layout/live-example/)
+
+## Installation
+
+### PNPM
+
+```shell
+pnpm add @lg-chat/chat-layout
+```
+
+### Yarn
+
+```shell
+yarn add @lg-chat/chat-layout
+```
+
+### NPM
+
+```shell
+npm install @lg-chat/chat-layout
+```
+
+## Overview
+
+`@lg-chat/chat-layout` provides a CSS Grid-based layout system for building full-screen chat interfaces with a side nav that can be collapsed or pinned.
+
+This package exports:
+
+- `ChatLayout`: The grid container and context provider
+- `ChatMain`: Content area component that positions itself in the grid
+- `useChatLayoutContext`: Hook for accessing layout state
+
+## Examples
+
+### Basic
+
+```tsx
+import { ChatLayout, ChatMain } from '@lg-chat/chat-layout';
+
+function MyChatApp() {
+ return (
+
+ {/* ChatSideNav will go here */}
+
+
Your chat content
+
+
+ );
+}
+```
+
+### With Initial State and Toggle Pinned Callback
+
+```tsx
+import { ChatLayout, ChatMain } from '@lg-chat/chat-layout';
+
+function MyChatApp() {
+ const handleTogglePinned = (isPinned: boolean) => {
+ console.log('Side nav is now:', isPinned ? 'pinned' : 'collapsed');
+ };
+
+ return (
+
+ {/* ChatSideNav will go here */}
+
+
Your chat content
+
+
+ );
+}
+```
+
+## Properties
+
+### ChatLayout
+
+| Prop | Type | Description | Default |
+| ------------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------- | ------- |
+| `children` | `ReactNode` | The content to render inside the grid layout (`ChatSideNav` and `ChatMain` components) | - |
+| `className` _(optional)_ | `string` | Custom CSS class to apply to the grid container | - |
+| `initialIsPinned` _(optional)_ | `boolean` | Initial state for whether the side nav is pinned (expanded) | `true` |
+| `onTogglePinned` _(optional)_ | `(isPinned: boolean) => void` | Callback fired when the side nav is toggled. Receives the new `isPinned` state as an argument | - |
+
+All other props are passed through to the underlying `
` element.
+
+### ChatMain
+
+| Prop | Type | Description | Default |
+| ---------- | ----------- | -------------------------- | ------- |
+| `children` | `ReactNode` | The main content to render | - |
+
+All other props are passed through to the underlying `
` element.
+
+**Note:** `ChatMain` must be used as a direct child of `ChatLayout` to work correctly within the grid system.
+
+## Context API
+
+### useChatLayoutContext
+
+Hook that returns the current chat layout context:
+
+```tsx
+const { isPinned, togglePin } = useChatLayoutContext();
+```
+
+**Returns:**
+
+| Property | Type | Description |
+| ----------- | ------------ | ---------------------------------------- |
+| `isPinned` | `boolean` | Whether the side nav is currently pinned |
+| `togglePin` | `() => void` | Function to toggle the pinned state |
+
+## Behavior
+
+### State Management
+
+- `ChatLayout` manages the `isPinned` state internally and provides it to all descendants via `ChatLayoutContext`
+- When `togglePin` is called:
+ 1. The `isPinned` state updates
+ 2. Grid columns resize smoothly via CSS transition
+ 3. The `onTogglePinned` callback fires (if provided) with the new state value
+- Descendant components can consume the context to:
+ - Read the current `isPinned` state
+ - Call `togglePin()` to toggle the sidebar
diff --git a/chat/chat-layout/package.json b/chat/chat-layout/package.json
new file mode 100644
index 0000000000..3d3b26e0c6
--- /dev/null
+++ b/chat/chat-layout/package.json
@@ -0,0 +1,54 @@
+
+{
+ "name": "@lg-chat/chat-layout",
+ "version": "0.0.1",
+ "description": "LeafyGreen UI Kit Chat Layout",
+ "main": "./dist/umd/index.js",
+ "module": "./dist/esm/index.js",
+ "types": "./dist/types/index.d.ts",
+ "license": "Apache-2.0",
+ "exports": {
+ ".": {
+ "require": "./dist/umd/index.js",
+ "import": "./dist/esm/index.js",
+ "types": "./dist/types/index.d.ts"
+ },
+ "./testing": {
+ "require": "./dist/umd/testing/index.js",
+ "import": "./dist/esm/testing/index.js",
+ "types": "./dist/types/testing/index.d.ts"
+ }
+ },
+ "scripts": {
+ "build": "lg-build bundle",
+ "tsc": "lg-build tsc",
+ "docs": "lg-build docs"
+ },
+ "publishConfig": {
+ "access": "public"
+ },
+ "dependencies": {
+ "@leafygreen-ui/emotion": "workspace:^",
+ "@leafygreen-ui/lib": "workspace:^",
+ "@leafygreen-ui/tokens": "workspace:^",
+ "@lg-tools/test-harnesses": "workspace:^"
+ },
+ "peerDependencies": {
+ "@lg-chat/leafygreen-chat-provider": "workspace:^"
+ },
+ "devDependencies": {
+ "@lg-chat/chat-window": "workspace:^",
+ "@lg-chat/input-bar": "workspace:^",
+ "@lg-chat/message": "workspace:^",
+ "@lg-chat/message-feed": "workspace:^",
+ "@lg-chat/title-bar": "workspace:^"
+ },
+ "homepage": "https://github.com/mongodb/leafygreen-ui/tree/main/chat/chat-layout",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/mongodb/leafygreen-ui"
+ },
+ "bugs": {
+ "url": "https://jira.mongodb.org/projects/LG/summary"
+ }
+}
diff --git a/chat/chat-layout/src/ChatLayout.stories.tsx b/chat/chat-layout/src/ChatLayout.stories.tsx
new file mode 100644
index 0000000000..85108f5011
--- /dev/null
+++ b/chat/chat-layout/src/ChatLayout.stories.tsx
@@ -0,0 +1,94 @@
+import React from 'react';
+import { ChatWindow } from '@lg-chat/chat-window';
+import { InputBar } from '@lg-chat/input-bar';
+import {
+ LeafyGreenChatProvider,
+ Variant,
+} from '@lg-chat/leafygreen-chat-provider';
+import { Message } from '@lg-chat/message';
+import { MessageFeed } from '@lg-chat/message-feed';
+import { TitleBar } from '@lg-chat/title-bar';
+import { StoryMetaType } from '@lg-tools/storybook-utils';
+import { StoryFn, StoryObj } from '@storybook/react';
+
+import { css } from '@leafygreen-ui/emotion';
+
+import { ChatLayout, type ChatLayoutProps, ChatMain } from '.';
+
+const meta: StoryMetaType = {
+ title: 'Composition/Chat/ChatLayout',
+ component: ChatLayout,
+ parameters: {
+ default: 'LiveExample',
+ },
+ decorators: [
+ Story => (
+
+
+
+ ),
+ ],
+};
+export default meta;
+
+const sideNavPlaceholderStyles = css`
+ background-color: rgba(0, 0, 0, 0.05);
+ padding: 16px;
+ min-width: 200px;
+`;
+
+const testMessages = [
+ {
+ id: '1',
+ messageBody: 'Hello! How can I help you today?',
+ isSender: false,
+ },
+ {
+ id: '2',
+ messageBody: 'I need help with my database query.',
+ },
+ {
+ id: '3',
+ messageBody:
+ 'Sure! I can help with that. What specific issue are you encountering?',
+ isSender: false,
+ },
+];
+
+const Template: StoryFn = props => (
+
+
+