Nextcloud App Development Workshop 260825
Appearance
Building your first Nextcloud app (beginner workshop) — watch on YouTube (Nextcloud channel, 2026-08-25, 56 min)
Presented by Anna Larch (Nextcloud Developer Relations, ex-Talk developer; security team), with Marcel Müller answering chat. Foundations of Nextcloud app development: where your code sits, what it may call, and how it talks to the rest of the server. Every example comes from a real app — Nextcloud Talk, Dashboard, Theming, and Files reminders.
Summary
- Public vs private API — build against
OCP\(stable, documented);OC\is internal/legacy and can be removed between versions. Breaking changes to public APIs are announced ~5 major versions ahead. If it isn't in the developer manual, assume it can change. - Request lifecycle —
index.php → routes → controller → service → mapper/DB → response. Auth, CSRF, and rate limiting run before the controller; brute-force throttling runs inside it. Controllers translate HTTP; business logic belongs in services. - Dependency injection — type-hint interfaces (
private IStorage $storage); the container resolves what the instance actually uses. The?string $userIdpattern is a nullable, immutable, cheap-to-filter user identifier resolved from the login. - Entities & type casting — cast entity fields explicitly (bool, DateTime) because MariaDB/MySQL/Oracle/PostgreSQL disagree on tinyint/boolean and datetime handling.
- Migrations —
preSchemaChange/changeSchema/postSchemaChange. Heavy data work goes into a one-time background job, never inline in an upgrade (her example: a 6–7 hour system-address-book update). - Indices — add at table creation when possible; for existing large tables register a missing-index listener so the admin applies it via
occin a maintenance window. Debug slow queries withEXPLAIN. - Event system — apps integrate by listening to core events (file created/modified/deleted, node updated), never by calling another app's code. Files reminders has no dependency on the Files app.
- Background jobs — extend
TimedJob; cron flavors are cron / webcron / ajax (ajax gives no time guarantee). Use the maintenance window with time-insensitive jobs for heavy syncs. - Scale traps — use folder search with limit/offset instead of full tree loads; chunk
INqueries to 1,000 items (Oracle's limit); avoid N+1 queries; test on current + previous majors; profile with Blackfire. - App store — validate info.xml, sign last, tarball = one top-level folder named the app ID, certificate request takes 2–4 days. Common rejections: CN/app-ID mismatch, bad archive structure, files changed after signing, invalid category.
Key takeaways
- Use only
OCP\; anything not in the developer manual can change. - Controllers translate HTTP; services do the work; entities/mappers own the data — with type casting.
- Heavy work (migrations, tree walks, per-user loops) belongs in background jobs.
- Integrate via events, never by calling another app's code.
- Chunk
INqueries to 1,000 for Oracle; test against the previous major too. - Sign last; the tarball must contain exactly one top-level folder named the app ID.
Resources
- Video: https://youtu.be/BQlm71K1AVM
- Nextcloud developer program and resources: https://nextcloud.com/developer/
- Developer documentation: https://docs.nextcloud.com
- Local transcript + study notes:
work/comfac-nextcloud/Audio Video/—BQlm71K1AVM-structured.md,BQlm71K1AVM-questions-details-needed.md