nextcloud-files

TypeScript helpers for building Nextcloud Files app integrations: WebDAV client, file/folder model, UI registry, and uploader.

Library
npm
v4.0.0
31stars
AGPL-3.0-or-later

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
73/100Good
Development Activity96
Maintenance96
Community28
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
74/100Good
Architecture82
Code Quality90
Innovation72
Learning Curve50

@nextcloud/files is the official TypeScript toolkit Nextcloud apps use to work with files and the Files app UI. It wraps the WebDAV protocol into a Nextcloud-aware client, models files and folders as typed Node/File/Folder objects with proxy-guarded attributes, and exposes a framework-agnostic registry so any app — Vue, vanilla JS, or otherwise — can add file actions, list filters, sidebar tabs, and new-menu entries to the Files app.

A separate upload entry point ships a shared, chunked Uploader with typed error handling and public-share support, while the dav entry point provides low-level WebDAV helpers (getClient, resultToNode, getFavoriteNodes) for listing, favoriting, and syncing content. Maintained by Nextcloud GmbH as one of the nextcloud-libraries packages that underpin the core Files app, it is the de facto dependency for any first- or third-party app that needs to read, write, or extend file browsing in Nextcloud.

What You Get

  • A typed WebDAV client (getClient, resultToNode, getFavoriteNodes) that maps DAV multistatus responses onto Node objects
  • A Node/File/Folder object model with proxy-guarded, read-only computed attributes (source, basename, mtime, permissions)
  • A framework-agnostic Files app UI registry for file actions, list actions, list filters, list headers, and new-menu entries
  • Web-component-based sidebar tab registration with a documented Vue defineCustomElement bridge
  • A shared, chunked Uploader singleton with p-queue concurrency, typed upload errors, and public-share support
  • Filename/path validation and unique-name generation helpers for safe renames and uploads

Common Use Cases

  • Registering a custom file action or “New”-menu entry so a third-party app can create or act on files from the Files app
  • Adding a custom sidebar tab (e.g. sharing details, metadata) via a native web component, usable from any frontend framework
  • Listing, favoriting, or syncing a folder’s contents by querying WebDAV and converting results into typed Node objects
  • Queuing chunked uploads (authenticated or public-share) with progress tracking and typed error handling

Under The Hood

Architecture The library is organized into four cohesive domains, each its own public entry point declared in package.json exports: node/ (the Node/File/Folder class hierarchy with a Proxy-wrapped attributes object enforcing read-only computed properties and mtime updates), dav/ (a WebDAV client wrapper around the webdav package that converts DAV multistatus responses into Node instances via resultToNode/getFavoriteNodes), ui/ (a global FilesRegistry singleton extending a typed EventTarget for registering file actions, list actions, filters, headers, and sidebar tabs), and upload/ (an Uploader class exposed through a global getUploader() singleton with chunking and typed errors). Data flows one way: WebDAV responses become Node instances, which are then handed to UI registry consumers that mutate attributes only through the proxy-guarded setter, keeping invariants like readonly computed properties intact. Because the Node model is the single boundary both dav/ (producer) and ui/ (consumer) depend on, it is the module most third-party code implicitly couples to.

Tech Stack Written almost entirely in TypeScript (ESM-only, "type": "module"), built with Vite via @nextcloud/vite-config’s createLibConfig into three separate bundles (index, dav, upload) with generated declaration files, plus a typedoc script for hosted API docs. Runtime dependencies are exclusively first-party Nextcloud helper packages (@nextcloud/auth, @nextcloud/axios, @nextcloud/capabilities, @nextcloud/l10n, @nextcloud/logger, @nextcloud/paths, @nextcloud/router, @nextcloud/sharing) alongside general-purpose utilities: webdav for the DAV protocol, axios-retry, is-svg, p-queue for upload concurrency, and typescript-event-target for the typed registry event target. Despite backing a Vue-based frontend, the library itself has no UI framework dependency — integration is via framework-agnostic web components.

Code Quality 34 .spec.ts test files live both under a top-level __tests__/ directory and colocated with source (e.g. getUploader.spec.ts), run through Vitest with @vitest/browser-playwright for browser-style DAV/uploader tests against a real @nextcloud/e2e-test-server, and @vitest/coverage-istanbul feeding Codecov. TypeScript runs in strict mode (with noImplicitAny: false the one relaxation) via a dedicated ts:check script, and ESLint runs the shared @nextcloud/eslint-config “recommendedLibrary” preset. Both are enforced as separate required CI jobs alongside a REUSE license-header check and Dependabot auto-merge automation, indicating a disciplined, actively maintained pipeline. Upload failures use dedicated typed error classes rather than generic exceptions.

What Makes It Unique Rather than shipping Vue components for Files app extension points, the UI integration surface (getFilesRegistry, sidebar tabs, file actions/filters/headers) is deliberately framework-agnostic, built on native CustomEvent/EventTarget and web components so apps written in Vue, vanilla JS, or any other framework can extend the Files app without adopting Vue as a hard dependency — the README documents an explicit defineCustomElement-based bridge for Vue consumers who still want reactive components. The object model’s use of a Proxy to enforce read-only computed attributes at the object level, rather than generating getter/setter boilerplate per field, is a clean, uncommon touch for this kind of domain model.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search