The SharePoint Framework is the biggest shift in SharePoint development since the move to the cloud. No more server-side trust, no more iframes — SPFx web parts are first-class citizens that run in the page's own context, in both classic and modern pages, on a modern open-source toolchain. If you come from farm solutions and add-ins, the technology stack will feel unfamiliar at first. This is the orientation I wish I'd had on day one.
The toolchain
SPFx is built on standard web tooling rather than Visual Studio and MSBuild. You'll install:
- Node.js (LTS) — the runtime everything runs on. SPFx is picky about Node versions; match the version your SPFx generator release supports.
- Yeoman + the SharePoint generator — scaffolds projects.
- Gulp — the task runner that builds, bundles, and serves.
- A code editor — Visual Studio Code is the community default, with great TypeScript support.
# Install the global tooling (one time)
npm install -g yo gulp @microsoft/generator-sharepoint
# Scaffold a new solution
md contoso-webparts
cd contoso-webparts
yo @microsoft/sharepoint
The generator interviews you: solution name, whether to deploy tenant-wide, component type (WebPart, Extension, Library), framework (None, React, or Knockout), and the web part name. Pick WebPart + No JavaScript framework for your first run so nothing hides the fundamentals.
The workbench
SPFx ships with a local workbench — a stand-alone HTML page that hosts your web part with mock data, no SharePoint required — and a hosted workbench that runs inside your real tenant at /_layouts/15/workbench.aspx, where your web part talks to real SharePoint data.
# Trust the dev certificate (one time per machine)
gulp trust-dev-cert
# Build and serve with live reload
gulp serve
The dev server bundles your code locally and serves it over HTTPS; the workbench loads it from localhost. Edit a file, save, and the workbench hot-reloads. That tight loop — no packaging, no deployment — is the single biggest productivity gain over the old models.
Anatomy of a web part
Your web part class extends BaseClientSideWebPart<TProps>. The two members you care about first are the render() method and the property pane:
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { IPropertyPaneConfiguration, PropertyPaneTextField }
from '@microsoft/sp-property-pane';
import { escape } from '@microsoft/sp-lodash-subset';
export interface IHelloWorldWebPartProps {
description: string;
}
export default class HelloWorldWebPart
extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
public render(): void {
this.domElement.innerHTML = `
<div>
<h2>Hello from SPFx</h2>
<p>${escape(this.properties.description)}</p>
<p>Site: ${escape(this.context.pageContext.web.title)}</p>
</div>`;
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [{
groups: [{
groupFields: [
PropertyPaneTextField('description', { label: 'Description' })
]
}]
}]
};
}
}
escape() around every property value before it touches innerHTML. SPFx gives you the raw string; you own output encoding. The SPFx linter flags unescaped interpolation for exactly this reason — don't suppress it.
The web part lifecycle
onInit()— async setup before first render: read context, fetch tokens, initialise services. Return a Promise and SPFx waits for it.render()— called on first display and whenever a property changes; paint your UI intothis.domElement.onPropertyPaneFieldChanged()/onDispose()— react to property edits and clean up.
The this.context object is your gateway to everything: pageContext (site/web/user info), spHttpClient for REST calls, and the AAD/Graph client factories covered in later articles.
From dev to deployment
When you're ready to ship, you build a production bundle and a deployment package:
gulp bundle --ship
gulp package-solution --ship
That produces a .sppkg in sharepoint/solution/. You upload it to the tenant App Catalog, approve any API permissions, and the web part becomes available to add to pages. With includeClientSideAssets set (the default), the JavaScript bundle is hosted by SharePoint itself — no separate CDN required, though you can use one for scale.
Where to go next
This gets you a working "no framework" web part and a feel for the loop. From here the real productivity comes from React + PnPjs for data-driven UIs, the property pane for configuration, and the AAD/Graph clients for talking to Microsoft 365 securely — each of which I cover in its own article. SPFx has a learning curve if you're coming from .NET, but it's modern, supported, and the only forward-looking way to extend SharePoint and Teams. The investment pays off quickly.