SharePoint  

Working with SharePoint Files vs Attachments in SPFx using PnPjs

When building SharePoint Framework (SPFx) solutions, developers often encounter two common ways of storing user content: Files and Attachments. While both approaches allow you to save binary data, they serve different purposes, have unique APIs, and should be used in the right context.

In this article, we’ll explore the difference between SharePoint Files and Attachments, how to work with them using PnPjs, and the best practices for choosing one over the other in enterprise projects.

Files vs Attachments in SharePoint

1. SharePoint Files (Document Libraries)

  • Stored in Document Libraries (e.g., Shared Documents).
  • Support metadata, versioning, content types, workflows, and document sets.
  • Ideal for managing official documents, collaboration, and records management.
  • Scalable for thousands of files with indexing and search integration.

👉 Example Use Cases: Policy documents, contracts, manuals, digital assets.

2. SharePoint Attachments (List Items)

  • Stored as attachments to list items.
  • Files are not standalone objects; they are bound to a list record.
  • Lack advanced metadata support and document management features.
  • Typically lightweight and best for supporting documents tied to structured data.

👉 Example Use Cases: Expense receipts attached to a reimbursement form, resumes attached to job applications, invoices attached to purchase requests.

Working with Files using PnPjs

With PnPjs files API, you can upload, read, update, and delete files in document libraries.

Upload a File

import { spfi } from "@pnp/sp";
import "@pnp/sp/files";
import "@pnp/sp/folders";

const sp = spfi(...);

async function uploadFile() {
  const folder = sp.web.getFolderByServerRelativePath("/sites/demo/Shared Documents");
  await folder.files.add("Report.pdf", fileContent, true); // true = overwrite
}

Get File Metadata

const file = await sp.web.getFileByServerRelativePath("/sites/demo/Shared Documents/Report.pdf").get(); 
console.log(file);

❌ Delete File

await sp.web.getFileByServerRelativePath("/sites/demo/Shared Documents/Report.pdf").delete();

📎 Working with Attachments using PnPjs

For list item attachments, PnPjs provides attachments APIs.

Add Attachment

import "@pnp/sp/attachments";

const list = sp.web.lists.getByTitle("Expenses");

await list.items.getById(1).attachmentFiles.add("receipt.jpg", fileContent);

Get All Attachments

const attachments = await list.items.getById(1).attachmentFiles(); 
console.log(attachments);

Remove Attachment

await list.items.getById(1).attachmentFiles.getByName("receipt.jpg").delete();

Best Practices: When to Use What?

Scenario Use Files Use Attchements
Require metadata, workflows, or approvals
Version control and collaboration
Supporting files linked to structured data
High-volume document storage
Small supporting docs (receipts, invoices)

Security Considerations

  • Files: Can leverage library-level permissions, role definitions, and advanced auditing.
  • Attachments: Security is limited to the list item’s permissions — no fine-grained file-level controls.

Conclusion

Both Files and Attachments are valid ways of storing user content in SharePoint, but the choice depends on context:

  • Use Files in Document Libraries for enterprise document management, compliance, and scalability.
  • Use Attachments in Lists for lightweight scenarios where files simply supplement list data.

By combining SPFx + PnPjs, you can seamlessly manage both approaches and build modern, efficient solutions.