Nextcloud
Audited from github.com/nextcloud/server
Nextcloud server is a self-hostable PHP 8.3 platform for file storage, sharing, and collaboration, exposing a stable OCP public API to first-class PHP apps and a Vue frontend that is transitioning from Webpack/Vue 2 to Vite/Vue 3.
- Language
- PHP
- Database
- MySQL
- Hosting
- Docker
- License
- AGPL-3.0
- Running for
- 9 years
- Team
- 20+ people
Why this architecture
Server internals (OC) are kept separate from a versioned public API (OCP) so that independently namespaced apps under apps/ can extend Nextcloud without depending on private implementation details, while database support is validated per-engine in CI.
Tech stack by layer
9 technologies · audited Sep 17, 2026- PHPImplements the core server, apps under apps/*, and the OCP public API in lib/public.
- MySQLSupported production database, exercised by dedicated CI workflows.(inferred)
- PostgreSQLSupported production database, exercised by dedicated CI workflows.(inferred)
- SQLiteSupported lightweight database for development and small instances.(inferred)
- DockerProvides the devcontainer image used for local development.
Nextcloud architecture diagram
Open SVGDiagram as text
- Web UI (Vue 3 · Vue 2 legacy) → Nextcloud server (PHP · OCP API): HTTP
- Sync clients (WebDAV · CalDAV) → DAV app (WebDAV · CalDAV · CardDAV): DAV
- DAV app (WebDAV · CalDAV · CardDAV) → Nextcloud server (PHP · OCP API): OCP
- Nextcloud server (PHP · OCP API) → Apps (apps/* modules): load apps
- Nextcloud server (PHP · OCP API) → Database (MySQL / PostgreSQL / SQLite): queries
- Nextcloud server (PHP · OCP API) → File storage (user files): read / write
Key architectural decisions
6 decisions- 01
Server core is PHP with a PSR-4 autoloaded public API surface
composer.json maps OCP\\ to lib/public and OC\\ to lib/private, giving apps a stable public API (OCP) while keeping server internals (OC) separate; core/ hosts framework-level controllers, migrations, and background jobs.
- 02
Frontend is mid-migration from Webpack/Vue 2 to Vite/Vue 3
build/frontend-legacy/package.json still builds Vue 2 apps with Webpack, while build/frontend/package.json builds a separate Vue 3 bundle with Vite; both are driven from build/demi.sh so old and new apps ship side by side during the transition.
- 03
Apps are first-class, independently namespaced PHP modules
The apps/ directory (files, dav, sharing, encryption, user_ldap, workflowengine, and more) each ship their own composer.json with an autoloader-suffix and psr-4 root, so bundled apps can be enabled, disabled, or replaced without touching core.
- 04
Database support is verified per-engine in CI rather than assumed
The workflow set (phpunit-mysql.yml, phpunit-pgsql.yml, phpunit-sqlite.yml, phpunit-mariadb.yml, phpunit-oci.yml, phpunit-mysql-sharding.yml) runs the PHPUnit suite against each supported database engine separately.
- 05
DAV protocol support is isolated in its own app with its own autoloader
apps/dav/composer/composer.json declares an OCA\\DAV\\ namespace rooted at apps/dav/lib, keeping CalDAV/CardDAV/WebDAV protocol handling (also covered by integration-dav.yml and integration-litmus.yml) separate from the core file storage code.
- 06
Static analysis runs through Psalm and Rector, not just PHPUnit
vendor-bin/psalm/composer.json and vendor-bin/rector/composer.json pin vimeo/psalm and rector/rector as isolated Composer bin dependencies, run via composer scripts (psalm, psalm:security, rector) referenced from build/rector.php and build/psalm-baseline.xml.
How Nextcloud is built
How Nextcloud is structured
Nextcloud server's PHP code is organized around the Composer autoload map in composer.json: OCP\ (the public API) maps to lib/public, OC\ (private server internals) maps to lib/private, and OC\Core\ maps to core/. The core/ directory hosts framework-level pieces — core/Controller, core/Db, core/Migrations, core/BackgroundJobs, core/Middleware — that every request passes through. Bundled functionality lives in apps/, with each subdirectory (files, dav, sharing, encryption, user_ldap, workflowengine, theming, and dozens more) representing an independently namespaced app. Frontend assets are split across two build pipelines under build/frontend (current, Vue 3 + Vite) and build/frontend-legacy (older, Vue 2 + Webpack), both invoked through the build/demi.sh script referenced from the root package.json.
Frontend
The root package.json declares dependencies on Vue 3 (vue": "^3.5.42"), Pinia for state management, @nextcloud/vue as the shared component library, and @nextcloud/router, @nextcloud/auth, and @nextcloud/dialogs for integration with server-rendered pages. build/frontend/package.json is a dedicated Vue 3 workspace whose build script runs vite build. Older parts of the UI have not migrated yet: build/frontend-legacy/package.json still depends on vue": "^2.7.16", vuex for state, and builds with webpack --node-env production. Both frontends share linting (eslint with a baseline-suppression file, build/eslint-baseline.json and build/eslint-baseline-legacy.json) and testing (vitest) tooling, and both are gated by the lint-eslint.yml and lint-stylelint.yml GitHub workflows.
Backend & APIs
The PHP backend targets PHP ^8.3 per composer.json, with required extensions including ext-curl, ext-gd, ext-mbstring, ext-zip, and ext-simplexml. The lib/private/legacy and lib/private trees hold the private OC\ implementation, while lib/public exposes the versioned OCP\ API that apps are expected to code against; an NCU\ namespace in lib/unstable marks APIs that have not yet stabilized. Static analysis is layered on top of PHPUnit: vendor-bin/psalm/composer.json pins vimeo/psalm for type checking (run via composer psalm, psalm:security, psalm:strict), and vendor-bin/rector/composer.json pins rector/rector for automated refactors (composer rector), both configured from build/psalm-baseline.xml and build/rector.php. vendor-bin/cs-fixer/composer.json runs friendsofphp/php-cs-fixer for style enforcement.
Data & persistence
Nextcloud is written to be database-agnostic at the application layer, and the CI workflow list is the clearest evidence of which engines are actually supported in practice: phpunit-mysql.yml, phpunit-mysql-sharding.yml, phpunit-mariadb.yml, phpunit-pgsql.yml, phpunit-sqlite.yml, and phpunit-oci.yml each run the PHPUnit suite (tests/phpunit-autotest.xml) against MySQL, sharded MySQL, MariaDB, PostgreSQL, SQLite, and Oracle respectively. phpunit-object-store-primary.yml and object-storage.yml additionally test S3-compatible and other object-storage backends as primary file storage, separate from the relational database used for metadata.
Build, test & deploy
JavaScript/TypeScript builds run through npm run build (mapped to build/demi.sh build), which coordinates both the Vite and Webpack pipelines, followed by build/npm-post-build.sh. Styling is compiled from core/css and per-app css directories with sass, including an icon-generation step (build/icons.mjs). Testing spans four frameworks: PHPUnit for PHP unit tests, Behat for PHP integration tests (vendor-bin/behat/composer.json), Vitest for JavaScript/TypeScript, and Playwright for end-to-end tests (@playwright/test in the root package.json, driven by playwright.yml). codeql.yml and static-code-analysis.yml run additional security and quality scans in CI, and reuse.yml checks SPDX license headers against the REUSE.toml policy.
Self-hosting notes
Nextcloud is designed to be self-hosted: the README documents manual server installation, appliance images, preinstalled devices, and hosted providers as install paths, alongside signup with a managed provider for users who do not want to run a server themselves. For local development, .devcontainer/Dockerfile builds an Ubuntu-based image with Apache, PHP 8.4 (with pgsql, sqlite, redis, imagick, and apcu extensions), Xdebug, and Node 22 via nvm, running Apache as a dedicated devcontainer user. Because database support is validated across MySQL, MariaDB, PostgreSQL, SQLite, and Oracle in CI rather than assumed, self-hosters are not locked into a single database engine when standing up a production instance.
Sources & repo audit
- Root composer.json (PSR-4 autoload map, PHP 8.3 platform)
- Root package.json (npm scripts, Vite/Sass build targets)
- build/frontend/package.json (Vue 3 + Vite bundle)
- build/frontend-legacy/package.json (Vue 2 + Webpack bundle)
- apps/dav/composer/composer.json (DAV app autoloader)
Independent analysis of repository at github.com/nextcloud/server. Spotted an inaccuracy? Use the claim form to request a correction.
Show this stack on your README or website
[](https://stackitfast.com/project/nextcloud)Paste it into your README. It shows your current stack and links to this page.
Scaffold it with your agent
Paste this prompt into Claude Code, Cursor, Windsurf or AGY to start a project with Nextcloud's architecture.
- 1Copy the promptThe full markdown spec, with every layer and decision.
- 2Open your AI toolClaude Code, Cursor, Windsurf or Copilot, in a new repo.
- 3Paste and scaffoldUse it as the first instruction; review before you ship.
# MISSION: Scaffold "Nextcloud" Production Architecture
You are an expert Senior Staff Software Architect and Full-Stack Engineer. Your mission is to scaffold and implement a production-grade, highly reliable, and modular codebase following the proven architecture of **Nextcloud**.
---
## 1. PROJECT SPECIFICATIONS & BENCHMARK
- **Reference Architecture**: Nextcloud
- **What It Does**: Nextcloud server is a self-hostable PHP 8.3 platform for file storage, sharing, and collaboration, exposing a stable OCP public API to first-class PHP apps and a Vue frontend that is transitioning from Webpack/Vue 2 to Vite/Vue 3.
- **Domain & Category**: Self-Hosted Collaborative Productivity Suite
- **Production Scale**: 20+ people
- **Development Mode**: CLASSIC
- **Architectural Rationale**: Server internals (OC) are kept separate from a versioned public API (OCP) so that independently namespaced apps under apps/ can extend Nextcloud without depending on private implementation details, while database support is validated per-engine in CI.
- **Live Website Reference**: https://nextcloud.com
- **Source Repository**: https://github.com/nextcloud/server
---
## 2. PRODUCTION TECH STACK
- **Full Stack Array**: PHP, JavaScript, TypeScript, Vue, MySQL, PostgreSQL, SQLite, Vite, Webpack
- **Primary Language(s)**: PHP, JavaScript, TypeScript
- **License of the reference repo**: AGPL-3.0
- **Frontend**: Vue — Powers the Vue 3 UI in build/frontend and the legacy Vue 2 UI in build/frontend-legacy.; Vite — Builds the current Vue 3 frontend bundle.; Webpack — Builds the legacy Vue 2 apps and core assets that have not migrated to Vite.; Pinia — State management store used by the Vue 3 frontend.
- **Backend & APIs**: PHP — Implements the core server, apps under apps/*, and the OCP public API in lib/public.
- **Data & persistence**: MySQL — Supported production database, exercised by dedicated CI workflows.; PostgreSQL — Supported production database, exercised by dedicated CI workflows.; SQLite — Supported lightweight database for development and small instances.
- **Infrastructure & deploy**: Docker — Provides the devcontainer image used for local development.
---
## 3. KEY ARCHITECTURAL DECISIONS (audited from https://github.com/nextcloud/server @ 014dc42)
1. **Server core is PHP with a PSR-4 autoloaded public API surface**: composer.json maps OCP\\ to lib/public and OC\\ to lib/private, giving apps a stable public API (OCP) while keeping server internals (OC) separate; core/ hosts framework-level controllers, migrations, and background jobs.
2. **Frontend is mid-migration from Webpack/Vue 2 to Vite/Vue 3**: build/frontend-legacy/package.json still builds Vue 2 apps with Webpack, while build/frontend/package.json builds a separate Vue 3 bundle with Vite; both are driven from build/demi.sh so old and new apps ship side by side during the transition.
3. **Apps are first-class, independently namespaced PHP modules**: The apps/ directory (files, dav, sharing, encryption, user_ldap, workflowengine, and more) each ship their own composer.json with an autoloader-suffix and psr-4 root, so bundled apps can be enabled, disabled, or replaced without touching core.
4. **Database support is verified per-engine in CI rather than assumed**: The workflow set (phpunit-mysql.yml, phpunit-pgsql.yml, phpunit-sqlite.yml, phpunit-mariadb.yml, phpunit-oci.yml, phpunit-mysql-sharding.yml) runs the PHPUnit suite against each supported database engine separately.
5. **DAV protocol support is isolated in its own app with its own autoloader**: apps/dav/composer/composer.json declares an OCA\\DAV\\ namespace rooted at apps/dav/lib, keeping CalDAV/CardDAV/WebDAV protocol handling (also covered by integration-dav.yml and integration-litmus.yml) separate from the core file storage code.
6. **Static analysis runs through Psalm and Rector, not just PHPUnit**: vendor-bin/psalm/composer.json and vendor-bin/rector/composer.json pin vimeo/psalm and rector/rector as isolated Composer bin dependencies, run via composer scripts (psalm, psalm:security, rector) referenced from build/rector.php and build/psalm-baseline.xml.
---
## 4. NON-NEGOTIABLE ARCHITECTURAL GUARDRAILS
1. **Monorepo & Modular Separation**:
- Structure as a Turborepo monorepo with strict package boundaries:
- `apps/web`: Application UI, routing, layouts, and server endpoints.
- `packages/ui`: Shared design tokens, CSS variables, and Radix UI primitive components.
- `packages/db`: Database schemas, client singleton, declarative migrations, and seed scripts.
- `packages/config`: Shared TypeScript, ESLint, and build configurations.
2. **Strict Type Safety & Zero `any` Policy**:
- Enable `strict: true`, `noImplicitAny: true`, and `strictNullChecks: true`.
- Validate ALL external inputs, API request bodies, and query parameters with **Zod** schemas before execution.
3. **Frontend & Rendering Guidelines**:
- Utilize Vite 6 with TanStack Router for fully type-safe routing. Manage server state and caching via TanStack Query v5 with optimistic UI updates.
4. **Design System & Aesthetics**:
- Keep every color, radius, shadow and font in a single token file (CSS variables) and consume tokens everywhere; never hardcode hex values in components.
- Prefer crisp 1px borders and one subtle shadow scale over blurry default shadows. Pair one sans-serif for body/headings with one monospace for tags, badges, metrics, and code.
5. **Data Layer & Reliability**:
- Write declarative schema definitions with foreign keys, composite indexes on queried filters, and automated timestamp triggers.
- Use connection pooling and prepared statements for serverless database execution.
---
## 5. STEP-BY-STEP SCAFFOLDING ROADMAP
- **Phase 1: Workspace & Root Config**: Initialize package manager, monorepo configuration (`turbo.json`, `tsconfig.base.json`, `package.json`).
- **Phase 2: Database Schema & Client**: Set up the data layer (MySQL, PostgreSQL, SQLite): client, connection pool, models, and migration scripts.
- **Phase 3: Design Tokens & UI Primitives**: Build accessible `Button`, `Input`, `Card`, `Badge`, and layout wrappers inside `packages/ui`.
- **Phase 4: Core Application Routes & Handlers**: Implement primary authentication, user session handling, and application routes.
- **Phase 5: Quality Assurance & Build Verification**: Run `tsc --noEmit`, ESLint, Prettier, and smoke test suites to ensure zero compilation or runtime errors.
---
## 6. EXECUTION INSTRUCTIONS
1. Review all specifications, architectural guardrails, and stack choices above.
2. Present the full monorepo directory tree structure.
3. Systematically generate the complete, production-ready codebase according to the 5-phase roadmap above — starting with the root workspace setup, followed by the database schema, UI design system package, and full-stack application routes until the repository is fully scaffolded and ready to run.Frequently asked about Nextcloud
What tech stack does Nextcloud use?
Nextcloud server is a PHP 8.3 application (PSR-4 autoloaded via composer.json) with a Vue-based frontend that is mid-migration from Webpack and Vue 2 to Vite and Vue 3, and it supports MySQL, MariaDB, PostgreSQL, SQLite, and Oracle as its database.
Does Nextcloud need a separate database server?
It supports several: dedicated CI workflows (phpunit-mysql.yml, phpunit-pgsql.yml, phpunit-sqlite.yml, phpunit-mariadb.yml, phpunit-oci.yml) run the test suite against MySQL, PostgreSQL, SQLite, MariaDB, and Oracle separately.
Can Nextcloud be self-hosted?
Yes, self-hosting is the primary distribution model; the repository ships a devcontainer (.devcontainer/Dockerfile) for development and documents manual server installation in its README.
How are Nextcloud apps structured?
Each app under apps/ (such as files, dav, sharing, or encryption) has its own composer.json with a dedicated PSR-4 namespace and autoloader suffix, letting apps be built, autoloaded, and enabled independently of core.
One email a month: new deep dives and stack trends
New source-audited architectures, head-to-head comparisons and the monthly stack report. No spam, unsubscribe anytime.
Similar architectures
- PrismaClassicNext-Generation Node.js & TypeScript ORM · 1M+ MAUShares TypeScript · JavaScript · PostgreSQL
- GiteaClassicLightweight Self-Hosted Git Service · 20+ peopleShares TypeScript · Vue · SQLite
- n8nHybridFair-Code Workflow Automation & AI Integrator · 20+ peopleShares TypeScript · Vue · PostgreSQL
- NocoDBHybridSmart Database Spreadsheet · 6-20 peopleShares TypeScript · Vue · PostgreSQL
- StrapiClassicHeadless CMS · 20+ peopleShares TypeScript · PostgreSQL · SQLite
- VaultwardenClassicLightweight Self-Hosted Password Vault · Solo / 2-5 peopleShares SQLite · PostgreSQL · MySQL