Building a SharePoint Copilot App with SPFx
A Step-by-Step Technical Guide to Copilot Components, Declarative Agents, Tools, Properties, Testing and Deployment
SharePoint Framework is moving beyond the traditional model of Web Parts and Extensions.
With SharePoint Copilot Apps, currently in Public Preview, Microsoft is introducing a development model in which SPFx components can participate directly in Microsoft 365 Copilot conversations.
This is an important architectural change.
Traditionally, an SPFx solution begins when a user navigates to a SharePoint page and interacts with a Web Part.
The interaction is generally:
User → SharePoint Page → SPFx Web Part → Business Logic → SharePoint or API
A Copilot Component changes the entry point.
The interaction can now begin with natural language:
User → Microsoft 365 Copilot → Declarative Agent → Tool → SPFx Copilot Component
The component is activated because the Agent interprets the user’s intent and determines that the interactive capability represented by the component is appropriate.
This article builds this architecture progressively.
The objective is not simply to make a component appear inside Copilot. We want to understand the complete contract:
Prompt
↓
Declarative Agent
↓
Tool Selection
↓
Structured Properties
↓
Copilot Component
↓
SPFx UI
↓
Packaging
↓
SharePoint App Catalog
↓
Microsoft 365 Copilot
Only after understanding this foundation should we introduce SharePoint data, Knowledge, Power Automate, APIs or Event Triggers.
1. Technical Learning Map
Before writing code, the following Microsoft documentation should remain open during the laboratory.
| Subject | Purpose | Official Microsoft resource |
|---|---|---|
| SharePoint Copilot Apps | Understand the complete model | Microsoft Learn — Overview of SharePoint Copilot Apps |
| First Copilot App | Official end-to-end tutorial | Microsoft Learn — Build your first SharePoint Copilot App |
| SPFx 1.24 Preview | Current Copilot Components implementation | Microsoft Learn — SPFx 1.24 Preview Release Notes |
| SPFx Overview | Review the base development model | Microsoft Learn — SharePoint Framework Overview |
| SPFx Platforms | Understand supported SPFx surfaces | Microsoft Learn — Supported Extensibility Platforms |
| SPFx Roadmap | Follow SPFx evolution | Microsoft Learn — SharePoint Framework Roadmap |
| Declarative Agents | Understand the Agent behind the component | Microsoft Learn — Microsoft 365 Copilot Extensibility |
| SharePoint App Catalog | Understand deployment | Microsoft Learn — SPFx deployment documentation |
The first three documents are particularly important because SharePoint Copilot Apps remain preview technology. APIs, schemas, tooling and even terminology can change before General Availability.
2. Understand What We Are Building
Before opening Visual Studio Code, we need a precise mental model.
We are not creating a conventional SPFx Web Part.
We are also not creating a Copilot Studio Agent.
We are creating an SPFx solution containing a Copilot Component together with the definition of a Declarative Agent.
The Copilot Component provides interactive UI.
The Declarative Agent provides the conversational and orchestration layer.
The Tool creates the semantic contract connecting them.
Therefore:
Declarative Agent = intelligence and orchestration
Tool = callable capability
Copilot Component = interactive experience
SPFx = development and packaging model
Microsoft 365 Copilot = conversational host
This distinction will become visible directly in the generated project structure.
3. Current Preview Requirements
Microsoft’s current tutorial requires the SPFx 1.24 preview line. The official tutorial states that SPFx 1.24 beta 2 or later is required, while the 1.24 release notes currently document beta.3 and installation through the npm @next tag.
Because this is preview software, it should be isolated from a production SPFx environment.
For example, if an organization currently develops production solutions using SPFx 1.23, upgrading every existing project merely to experiment with Copilot Components would be unnecessary and risky.
A better approach is a separate development environment.
Conceptually:
Production SPFx environment
Stable supported version
and separately:
Copilot Component laboratory
SPFx 1.24 preview
This gives us freedom to experiment without coupling preview dependencies to production solutions.
4. Install the SPFx Preview Generator
The current SPFx 1.24 preview documentation uses:
npm install @microsoft/generator-sharepoint@next --global
The @next tag is significant.
We are deliberately requesting the preview version rather than the normal production generator.
After installation, verify the environment before scaffolding the solution.
The purpose of this first step is simply to establish that the development machine is using a generator that understands the Copilot Component project type.
Do not begin adding SharePoint APIs, PnPjs or additional packages yet.
Our first milestone is much smaller:
Can we scaffold and execute the smallest possible Copilot Component?
5. Create a Clean Project Folder
Create a dedicated folder for the experiment.
For example:
C:\Dev\CopilotComponents\ProjectStatus
Open a terminal in this directory and start the SharePoint Framework generator.
The exact interactive generator experience can evolve during preview, but the important selection is the creation of a Copilot Component rather than a traditional Web Part or Extension.
For our laboratory, use a descriptive solution name such as:
ProjectStatusCopilot
and a component such as:
ProjectStatus
The naming is important because Tools later become semantic capabilities visible to the Agent.
Names such as:
Tool1Component1Test
quickly become confusing.
Prefer names that communicate business meaning.
6. Choose a Starter Template
The current generator provides three starter approaches:
Minimal
No framework
React
For our first experiment, Minimal is the best choice.
The objective is not yet to create a sophisticated interface.
The objective is to expose the architecture.
Minimal removes unnecessary application structure and lets us concentrate on the relationship between:
Agent → Tool → Properties → Component
Once this model is understood, a React implementation becomes straightforward for an experienced SPFx developer.
React becomes particularly attractive when the same UX logic will eventually be reused between conventional Web Parts and Copilot Components.
7. Examine the Generated Project Before Changing Anything
This is one of the most important steps.
Do not immediately start coding.
Inspect the generated project.
A SharePoint Copilot App contains two architectural areas that deserve separate attention.
Conceptually:
ProjectStatusCopilot│├── src│ └── copilotComponents│ └── projectStatus│├── copilot│ ├── manifest.json│ ├── declarativeAgent.json│ ├── ai-plugin.json│ └── instruction.txt│├── config│└── package.json
The exact generated structure can change during preview, but the architectural separation is fundamental.
The src/copilotComponents area belongs primarily to the interactive experience.
The copilot area belongs primarily to the Agent definition.
Already we can see something very important:
A SharePoint Copilot App packages Agent architecture and application UI in the same SPFx solution.
8. Understand the Copilot Component
A conventional SPFx Web Part normally extends:
BaseClientSideWebPart
A Copilot Component instead uses the Copilot-specific component model based on:
BaseCopilotComponent
This difference represents the host boundary.
A Web Part participates in the SharePoint page lifecycle.
A Copilot Component participates in the Microsoft 365 Copilot canvas lifecycle.
This is why a Copilot Component should not simply be interpreted as “a Web Part displayed somewhere else.”
The host contract is different.
The underlying React components, business services and styling can potentially be shared, but the host-specific component is different.
This distinction becomes especially important when designing reusable enterprise SPFx architectures.
9. Understand the Component Manifest
The component manifest describes capabilities available to the Copilot host.
Two concepts are particularly important:
display modes
and:
tools
A component can currently declare supported display modes such as:
inline
and:
fullscreen
Inline allows the component to participate naturally within the conversation.
Fullscreen provides more space for complex interactive experiences.
The host ultimately controls presentation, but the component declares what it supports.
This is an important UX difference from a conventional SharePoint Web Part.
We are designing for a conversation canvas, not merely a page canvas.
10. Define the Tool
Now we reach the central concept.
The Copilot Component declares one or more Tools.
Conceptually, our manifest could describe something like:
ProjectStatusTool
with a description similar to:
Displays an interactive status view for a specified project.
This description matters.
The Agent uses semantic information about available capabilities when determining what should be invoked.
The Tool is therefore not merely a technical identifier.
It is part of the orchestration contract.
Compare:
Tool1
with:
ProjectStatusTool
and compare:
Displays data
with:
Displays the current project status, progress and risk information for a specified project.
The second design gives the orchestration layer significantly better semantic information.
11. Define the Properties Contract
A Tool can expose a properties schema.
For our first experiment, we need only one meaningful property:
projectName
Conceptually:
ProjectStatusTool projectName: string
This creates the bridge between natural language and application state.
Suppose the user says:
“Show me Project Atlas.”
The Agent interprets the sentence.
Instead of passing the entire sentence into the UI, it can invoke the Tool with structured information:
projectName = "Atlas"
The component receives that property.
The architecture becomes:
Natural language
↓
Semantic interpretation
↓
Structured parameter
↓
SPFx component
This is one of the most important patterns in Agent architecture.
The LLM deals with ambiguity.
The application receives structure.
12. Read Properties Inside the Component
The component can access the parameters supplied by the Agent through its properties.
Conceptually:
protected render(): void { const projectName = this.properties.projectName;}
At this stage, resist the temptation to call SharePoint.
Instead, render something extremely simple.
For example:
PROJECT STATUSProject: AtlasStatus: At RiskProgress: 45%Open Risks: 5
Only projectName needs to be dynamic initially.
The remaining values can be static.
This may seem simplistic, but it creates an excellent architectural test.
If the user says:
“Show Project Atlas”
and the component renders:
Project: Atlas
we have proven a surprisingly important chain:
Prompt → Agent → Tool → Parameter → SPFx
That is our first milestone.
13. Understand the Declarative Agent
Now move from the component side to the copilot folder.
The declarativeAgent.json defines the Agent that makes our capabilities available through Microsoft 365 Copilot.
A simplified conceptual definition resembles:
{ "version": "v1.8", "name": "Project Status Agent", "instructions": "$[file('instruction.txt')]", "conversation_starters": [ { "title": "Project status", "text": "Show me Project Atlas" } ], "actions": [ { "id": "projectStatusAction", "file": "ai-plugin.json" } ]}
New projects created by the latest documented SPFx 1.24 beta.3 tooling target the Declarative Agent manifest v1.8.
The exact generated content should be preserved initially.
Our goal is first to understand what the generator created before customizing it heavily.
14. Understand instruction.txt
The instruction.txt file contains behavioral Instructions for the Agent.
For our laboratory, the Instructions should remain intentionally narrow.
Conceptually:
You are a project status assistant.Help users inspect project status information.When the user asks to display a project status,use the available project status capability.Do not invent project names or project information.
Notice what is absent.
We are not placing API URLs here.
We are not putting SharePoint credentials here.
We are not describing React rendering.
Instructions belong to the Agent behavior layer.
Implementation belongs elsewhere.
This separation becomes increasingly important as solutions grow.
15. Understand ai-plugin.json
The ai-plugin.json file describes Actions exposed to the model.
This participates in connecting the Declarative Agent to the capabilities provided by the application.
The important concept for the first laboratory is not memorizing every property in the JSON schema.
It is understanding the relationship:
Declarative Agent
↓
Action
↓
Tool
↓
Copilot Component
The Agent does not directly instantiate arbitrary JavaScript.
The solution describes capabilities through declarative contracts.
This is one of the reasons Tool naming and descriptions deserve architectural attention.
16. Understand copilot-agent.json
The build system also needs to understand which Copilot Components belong to the Agent.
The project therefore contains configuration connecting the Agent and its components.
During build, SPFx combines the Declarative Agent definition with the Copilot Component definitions, including their Tools and properties.
The result is assembled into the deployable solution.
This is important because the Agent and component are authored as distinct concerns but packaged as one application.
17. Run the Local Development Server
Once the generated project is understood, start the local development environment.
The current Microsoft documentation uses:
heft start --nobrowser
This starts the local development server without automatically opening a conventional SharePoint Workbench.
That distinction matters because Copilot Components have their own development host.
We are now ready for the Copilot Workbench.
18. Open the Copilot Workbench
Microsoft provides a dedicated Copilot Workbench for testing locally hosted Copilot Components.
The current path is:
/_layouts/15/copilotworkbench.aspx
Therefore, in a tenant such as:
https://contoso.sharepoint.com
the Workbench would be:
https://contoso.sharepoint.com/_layouts/15/copilotworkbench.aspx
The Workbench loads the locally hosted component and allows us to iterate without performing a complete App Catalog deployment after every code change.
This gives us the development loop:
Code
↓
heft
↓
localhost
↓
Copilot Workbench
↓
Test
↓
Modify
↓
Test again
This should be our primary inner development loop.
19. Test the Component Before Testing Intelligence
The first Workbench test should be deliberately boring.
Does the component load?
Does it render?
Does inline mode work?
Does fullscreen work if configured?
Does it receive the expected properties?
Does a changed property change the initial rendering?
Only after these behaviors are correct should we evaluate Agent orchestration.
This separation is important during troubleshooting.
If the component itself does not render, there is no reason to investigate Agent Instructions.
If the component renders correctly but the Agent does not invoke it, then we investigate Tool metadata, Actions and Instructions.
One variable at a time.
20. Test the Conversational Contract
Now test the actual intent.
For example:
“Show me Project Atlas.”
The expected logical sequence is:
User ↓"Show me Project Atlas" ↓Declarative Agent ↓ProjectStatusTool ↓projectName = "Atlas" ↓ProjectStatusCopilotComponent ↓SPFx rendering
Do not judge the test only by visual appearance.
Verify the semantic contract.
Did the Agent select the correct Tool?
Was Atlas extracted correctly?
Did the component receive Atlas?
Did the correct UI render?
This is Agent application testing rather than merely UI testing.
21. Test Display Modes
A Copilot Component can currently support two important presentation modes:
inline
and:
fullscreen
Inline is appropriate for compact information embedded naturally within the conversation.
Fullscreen is useful when the experience becomes richer: dashboards, maps, tables, forms, complex charts or multi-control applications.
The component can inspect its current display mode through the host context and can request expansion to fullscreen.
The host retains control over collapsing back to inline.
This creates a useful UX principle:
Start conversationally; expand when interaction requires application space.
That is fundamentally different from traditional SharePoint navigation.
22. Package the Solution
Once the component works in the Copilot Workbench, the next stage is packaging.
During the build, SPFx combines the component assets and Copilot definitions.
The generated intermediate Copilot content can be inspected under:
temp/copilot
This folder is particularly useful while learning because it helps us see what the build pipeline generated from our source definitions.
The final deployment artifact remains familiar to every SPFx developer:
.sppkg
This is one of the elegant aspects of the model.
We have introduced an Agent, Tools and a conversational UI surface without abandoning the SPFx packaging model.
23. Understand Client-Side Asset Hosting
The solution configuration can use:
"includeClientSideAssets": true
When enabled, the JavaScript assets are included in the .sppkg and hosted automatically within the customer’s Microsoft 365 tenant.
For this model, that means we do not necessarily need to provision a separate Azure Storage account or external CDN simply to host the Copilot Component assets.
The deployment architecture becomes much simpler:
Build
↓
.sppkg
↓
Tenant
↓
Microsoft-hosted component assets
This is particularly useful for enterprise deployment and tenant portability.
24. Deploy to the SharePoint App Catalog
Upload the .sppkg to the SharePoint App Catalog.
This looks familiar, but something important now happens behind the scenes.
A SharePoint Copilot App does not contain only client-side SPFx assets.
It also contains a Declarative Agent.
When the package is deployed, the Declarative Agent is synchronized with the tenant Agent Catalog.
The current preview documentation instructs the administrator to select:
Add to Teams
The label is misleading.
Microsoft explicitly notes that the label will be changed in the future because the operation now also publishes the associated Agent.
Conceptually:
.sppkg
↓
SharePoint App Catalog
↓
Deploy
↓
Declarative Agent synchronization
↓
Tenant Agent Catalog
↓
Microsoft 365 Copilot
There is no separate manual Agent publishing process for this specific model.
25. Test in Microsoft 365 Copilot
After synchronization completes, locate the Agent through the Microsoft 365 Copilot experience.
Now repeat the same scenario used during development:
“Show me Project Atlas.”
The result should no longer depend on the local Workbench.
The deployed Declarative Agent should identify the capability and invoke the packaged Copilot Component.
At this point we have completed the entire lifecycle:
Create
↓
Configure
↓
Run locally
↓
Test
↓
Package
↓
Deploy
↓
Use in Microsoft 365 Copilot
That is our first complete SharePoint Copilot App.
26. Versioning Requires Special Attention
Preview development introduces an important Agent lifecycle consideration.
Changes to the Declarative Agent definition need to be recognized as a new definition.
The Microsoft documentation specifically warns developers to update the Declarative Agent version when changing Agent-side elements such as Instructions, Conversation Starters or Actions.
Otherwise, Microsoft 365 Copilot may continue using a previously synchronized Agent definition.
This can produce an extremely misleading troubleshooting situation:
new .sppkg deployed
but:
old Agent behavior remains
Therefore, when debugging a deployment, distinguish:
SPFx component change
from:
Declarative Agent change
The latest SPFx 1.24 beta.3 tooling has also improved version handling for Copilot Component updates and now validates Declarative Agent manifests at build time, reducing some preview-era deployment errors.
27. Only Now Connect SharePoint
Once the static component works end-to-end, evolve it.
Create a SharePoint list:
Projects
with fields such as:
TitleStatusProgressRiskLevelOpenRisks
Example:
AtlasAt Risk45High5
The Tool still receives:
projectName = Atlas
But the SPFx component now uses that value to retrieve the actual SharePoint item.
The architecture becomes:
User
↓
Agent
↓
ProjectStatusTool
↓
projectName = Atlas
↓
Copilot Component
↓
SPFx
↓
SharePoint
↓
Projects List
↓
Interactive UI
Now our Copilot App has become a real SharePoint application.
28. Do Not Add Graph Automatically
Because this is an SPFx solution, it may be tempting to introduce Microsoft Graph immediately.
That is unnecessary if the data already exists in SharePoint and can be accessed appropriately using the native SPFx/SharePoint development model.
Our architectural sequence should remain:
Native SPFx + SharePoint first
then:
Microsoft Graph when the requirement crosses into Microsoft 365 capabilities that justify it
and:
Custom APIs when business capabilities require them
The presence of Copilot does not change this principle.
29. Add Knowledge as a Separate Capability
The next evolution is not another UI feature.
It is Knowledge.
Suppose the SharePoint site also contains:
Project Governance Policy.docxRisk Management Standard.pdfProject Status Guidelines.docx
These documents can participate in the Agent’s Knowledge architecture.
Now two user requests produce different paths.
The user asks:
“Show me Project Atlas.”
The Agent invokes the Tool and renders the Copilot Component.
But if the user asks:
“Why is a project with this risk level classified as At Risk?”
the Agent may use Knowledge, Retrieval and Grounding.
Therefore:
SHOW ↓Tool ↓Copilot Component
while:
EXPLAIN ↓Knowledge ↓Retrieval ↓Grounding ↓Answer
This distinction is fundamental.
UI is not Knowledge.
Knowledge is not Action.
30. Add an Action Only After Read Scenarios Work
The next evolution could be:
“Create a mitigation action for Atlas.”
Now the user wants to change enterprise state.
This should be implemented as a controlled business capability.
For example:
CreateProjectMitigation
The architecture could use Power Automate or an API depending on the requirement.
Conceptually:
Agent
↓
CreateProjectMitigation
↓
Power Automate
↓
SharePoint
↓
Project Actions
The Copilot Component can subsequently display the resulting mitigation action.
Now SPFx and the Agent are participating in the same business process without confusing their responsibilities.
31. Event Triggers Come Later
Only after the previous layers are understood should autonomous behavior be introduced.
Suppose a new item with:
RiskLevel = Critical
is created in SharePoint.
An Event Trigger could initiate Agent processing.
The architecture then reverses:
SharePoint
↓
Event Trigger
↓
Agent
↓
Knowledge + reasoning
↓
Tool / Action
↓
Power Automate
↓
Escalation
This is significantly more advanced than our initial Copilot Component.
It should therefore be treated as another laboratory rather than included in the first implementation.
32. Troubleshooting Model
When something fails, troubleshoot the architecture layer by layer.
If nothing renders, investigate the Copilot Component.
If properties are incorrect, investigate the Tool contract.
If the Tool is not selected, investigate Tool name, description, Agent Action and Instructions.
If local testing works but deployed testing fails, investigate packaging, App Catalog deployment and Agent synchronization.
If the Agent appears unchanged after deployment, investigate Agent versioning.
If SharePoint data fails while static data works, investigate only the SharePoint integration layer.
This gives us a disciplined debugging chain:
Component↓Properties↓Tool↓Agent↓Workbench↓Package↓App Catalog↓Agent Catalog↓Microsoft 365 Copilot↓SharePoint Data
Never change all of these simultaneously.
33. Current Preview Limitations
The preview status should influence architectural decisions.
At the current stage, Microsoft documents that Copilot Components initially render only in the Microsoft 365 Copilot UX.
Microsoft commercial marketplace distribution is not yet supported.
Tool names must currently be unique across deployed SharePoint Copilot App solutions because duplicate Tool names can cause one registration to be ignored.
The model, APIs and schemas can still change.
Licensing during preview is also unusual: Microsoft currently states that a Microsoft 365 Copilot license is not required to build, deploy or run SharePoint Copilot Apps during the preview period. Microsoft has not finalized the licensing model for General Availability.
None of these preview conditions should be assumed to remain true for production planning.
34. Our Recommended Laboratory Sequence
We should learn the technology through small architectural increments rather than constructing a large Agent immediately.
| Lab | What we add | What we prove |
|---|---|---|
| 1 | Minimal Copilot Component | SPFx runs in Copilot |
| 2 | projectName property | Agent → structured parameter → UI |
| 3 | Inline/fullscreen | Copilot hosting model |
| 4 | Declarative Agent Instructions | Behavioral control |
| 5 | SharePoint Projects List | SPFx → SharePoint data |
| 6 | SharePoint Knowledge | Retrieval and Grounding |
| 7 | Create Action | Agent can change state |
| 8 | Power Automate | Deterministic execution |
| 9 | Event Trigger | SharePoint event → Agent |
| 10 | Security review | Identity and authorization |
| 11 | ALM | DEV → TEST → PROD strategy |
| 12 | Shared UX | Reusable SPFx architecture |
This sequence gives us one new variable at a time.
35. Final Technical Summary
| Component | Role | Direction |
|---|---|---|
| Microsoft 365 Copilot | Conversational host | User ↔ Agent |
| Declarative Agent | Reasoning and orchestration | Prompt → capability |
instruction.txt | Behavioral guidance | Instructions → Agent |
declarativeAgent.json | Agent definition | Configuration → Agent |
ai-plugin.json | Action metadata | Agent → capabilities |
| Tool | Semantic capability contract | Agent → Component |
propertiesSchema | Structured input contract | Tool → properties |
BaseCopilotComponent | Copilot-specific SPFx host | Host → UI |
| Copilot Component | Interactive experience | Agent → UI |
this.properties | Invocation parameters | Agent → SPFx |
hostContext.displayMode | Host presentation state | Copilot → Component |
| Copilot Workbench | Local development host | localhost → test |
heft | SPFx build/development tooling | Source → build |
temp/copilot | Generated Copilot package content | Build inspection |
.sppkg | Deployable solution | DEV → Tenant |
| SharePoint App Catalog | Deployment lifecycle | Package → tenant |
| Tenant Agent Catalog | Agent availability | Deployment → Copilot |
| SharePoint List | Structured business data | SPFx ↔ SharePoint |
| SharePoint Knowledge | Enterprise information | SharePoint → Agent |
| Power Automate | Deterministic execution | Agent → process |
| Event Trigger | External event entry point | SharePoint → Agent |
Conclusion
Building a SharePoint Copilot App with SPFx is not simply another way to create a Web Part.
It introduces a new application activation model.
Traditional SPFx begins with navigation:
Page → Web Part → Interaction
Copilot Components can begin with intent:
Prompt → Agent → Tool → Component → Interaction
The technical bridge between these worlds is the Tool contract.
The Agent understands natural language.
The Tool exposes a semantic capability.
The properties schema transforms the Agent’s interpretation into structured application input.
The Copilot Component receives those properties.
SPFx renders the interactive experience.
The .sppkg packages both the application experience and Declarative Agent architecture.
The SharePoint App Catalog deploys the solution.
Microsoft 365 Copilot becomes the conversational host.
Once this basic chain works, the architecture can grow deliberately:
Prompt
↓
Declarative Agent
↓
Tool
↓
Copilot Component
↓
SPFx
↓
SharePoint
and separately:
SharePoint Knowledge
↓
Retrieval
↓
Grounding
↓
Agent
and later:
Agent
↓
Action
↓
Power Automate / API
↓
SharePoint or System of Record
and eventually:
SharePoint Event
↓
Event Trigger
↓
Agent
↓
Reasoning
↓
Action
This progressive model is much safer than attempting to combine everything in the first application.
The first objective should therefore remain deliberately small:
Create one Minimal Copilot Component, expose one Tool, pass one property and render that property successfully in the Copilot Workbench.
Once that works, we have crossed the fundamental technical boundary.
We are no longer merely building an SPFx component for a page.
We are building an SPFx capability that an Agent can discover and invoke from a conversation.
