Artifacts & Code Blocks
Relevant source files
The following files were used as context for generating this wiki page:
Artifacts and Code Blocks represent the primary mechanisms by which the Bolt assistant communicates executable actions and structured code to the user and the system. While Code Blocks are used for syntax-highlighted display within the chat interface, Artifacts are specialized containers that encapsulate "Actions"—such as file creations or shell commands—that can be executed within the sandboxed WebContainer environment.
These components are processed through a streaming message parser that identifies specific XML-like tags within the LLM's response, transforming raw text into interactive UI elements and state updates within the workbench.
Sources: app/lib/runtime/message-parser.ts:7-12, app/components/chat/Artifact.tsx:37-45
Artifact System Architecture
Artifacts are defined by <boltArtifact> tags which contain metadata like id and title. They serve as logical groupings for one or more <boltAction> elements. The system uses a StreamingMessageParser to detect these tags in real-time as the AI generates its response.
Component Hierarchy and Data Flow
The data flow begins at the parser, updates a global store, and reflects in the UI components.
The diagram above shows how raw text from the AI is intercepted and converted into manageable state and interactive UI components.
Sources: app/lib/runtime/message-parser.ts:60-120, app/lib/stores/workbench.ts:210-230
Key Data Structures
| Type | Fields | Description |
|---|---|---|
ArtifactState | id, title, closed, runner | Maintains the state of an artifact and its execution runner. |
ArtifactCallbackData | messageId, id, title | Data passed when an artifact tag is opened or closed. |
ActionCallbackData | artifactId, messageId, actionId, action | Encapsulates specific action details (file or shell). |
Sources: app/lib/lib/stores/workbench.ts:16-21, app/lib/runtime/message-parser.ts:16-30
Message Parsing Logic
The StreamingMessageParser maintains an internal MessageState to handle the incremental nature of LLM streaming. It looks for specific constants to delimit artifacts and actions.
ARTIFACT_TAG_OPEN:<boltArtifactARTIFACT_TAG_CLOSE:</boltArtifact>ARTIFACT_ACTION_TAG_OPEN:<boltActionARTIFACT_ACTION_TAG_CLOSE:</boltAction>
When the parser identifies an artifact, it injects a placeholder div with a specific class (__boltArtifact__) and data-message-id. The Markdown component later recognizes this class to render the actual Artifact React component.
Sources: app/lib/runtime/message-parser.ts:7-10, app/components/chat/Markdown.tsx:30-40
The sequence shows the lifecycle of an artifact from detection to execution of its internal actions.
Sources: app/lib/runtime/message-parser.ts:65-110, app/lib/stores/workbench.ts:240-260
Code Blocks & Syntax Highlighting
Code Blocks are used for displaying source code that is not necessarily part of an executable artifact. They are rendered via the CodeBlock component, which utilizes the shiki library for high-quality syntax highlighting.
CodeBlock Features
- Automatic Language Detection: Extracts language from markdown fences (e.g.,
language-typescript). - Copy to Clipboard: A transient UI overlay allows users to copy the raw code content.
- Theme Support: Supports
light-plusanddark-plusthemes.
// app/components/chat/CodeBlock.tsx:43-55
useEffect(() => {
if (language && !isSpecialLang(language) && !(language in bundledLanguages)) {
logger.warn(`Unsupported language '${language}'`);
}
const processCode = async () => {
setHTML(await codeToHtml(code, { lang: language, theme }));
};
processCode();
}, [code]);
Sources: app/components/chat/CodeBlock.tsx:1-60
UI Integration: Artifact Component
The Artifact component (found in app/components/chat/Artifact.tsx) provides the visual interface for artifacts within the chat.
Functionality
- Toggle Workbench: Clicking the artifact header toggles the visibility of the workbench via
workbenchStore.showWorkbench. - Action Visibility: A caret button allows users to expand or collapse the list of actions (file creations, shell commands) within the artifact.
- Status Indicators: Each action displays a status icon (pending, running, complete, or failed).
- Action Types:
- File Action: Displays the file path being created.
- Shell Action: Renders a specialized
ShellCodeBlockcontaining the command.
Sources: app/components/chat/Artifact.tsx:50-100, app/components/chat/Artifact.tsx:135-170
Action Status Icons
| Status | Icon / Animation | Color Variable |
|---|---|---|
running | i-svg-spinners:90-ring-with-bg | --bolt-elements-loader-progress |
pending | i-ph:circle-duotone | --bolt-elements-textTertiary |
complete | i-ph:check | --bolt-elements-icon-success |
failed | i-ph:x | --bolt-elements-icon-error |
Sources: app/components/chat/Artifact.tsx:155-165, app/components/chat/Artifact.tsx:184-205
Markdown Rendering
The Markdown component serves as the bridge between raw text and interactive components. It uses react-markdown with rehype and remark plugins.
- Artifact Detection: It scans for
divelements with the__boltArtifact__class and replaces them with theArtifactReact component. - Pre-formatted Text: It intercepts
<pre>tags. If a<code>child is found, it renders theCodeBlockcomponent instead of standard HTML<pre>. - Sanitization: Uses
rehype-sanitizewith a custom schema that allows the__boltArtifact__class anddata-*attributes required for artifact identification.
Sources: app/components/chat/Markdown.tsx:28-60, app/utils/markdown.ts:65-75
Conclusion
Artifacts and Code Blocks form the interactive core of the Bolt interface. By combining a streaming parser with a centralized workbench store and specialized React components, the system can dynamically transform AI suggestions into executable project structures and highlighted code displays while maintaining real-time feedback for the user.