| name | nextcloud-impl-app-scaffold |
| description | Use when creating a new Nextcloud app, setting up info.xml, configuring Application.php, or understanding app directory layout. Prevents incorrect info.xml fields, wrong namespace conventions, and missing IBootstrap implementation. Covers directory structure conventions, info.xml manifest with all fields and constraints, Application.php with IBootstrap lifecycle, namespace conventions and autoloading, and the official app generator. Keywords: info.xml, Application.php, IBootstrap, app scaffold, namespace, autoloading, app generator, appinfo, new app setup, directory structure, info.xml guide, app registration..
|
| license | MIT |
| compatibility | Designed for Claude Code. Requires Nextcloud 28+. |
| metadata | {"author":"OpenAEC-Foundation","version":"1.0"} |
nextcloud-impl-app-scaffold
Quick Reference
App Directory Layout
myapp/
├── appinfo/
│ ├── info.xml # App manifest (REQUIRED)
│ └── routes.php # Route definitions
├── lib/
│ ├── AppInfo/
│ │ └── Application.php # Bootstrap entry point (IBootstrap)
│ ├── Controller/ # HTTP controllers
│ ├── Service/ # Business logic layer
│ ├── Db/ # Entity classes and mappers
│ ├── Listener/ # Event listeners
│ ├── Middleware/ # Request middleware
│ ├── Migration/ # Database migrations
│ └── Command/ # OCC CLI commands
├── src/ # Vue.js frontend source
│ ├── main.js
│ ├── App.vue
│ └── components/
├── css/ # Stylesheets (CSS/SCSS)
├── img/
│ └── app.svg # App icon (used as navigation icon)
├── js/ # Compiled JS output (generated)
├── templates/ # PHP templates
│ └── main.php
├── tests/ # PHPUnit tests
├── l10n/ # Translation files
├── webpack.config.js
├── package.json
├── composer.json
└── LICENSE
info.xml Required Fields
| Field | Constraint |
|---|
id | Lowercase ASCII + underscore only, MUST match app directory name |
name | Human-readable app name |
summary | Short description for app store listing |
description | Full description, supports Markdown via <![CDATA[]]> |
version | Semantic versioning (no build metadata) |
licence | SPDX identifier (AGPL-3.0-or-later, MIT, etc.) |
author | Developer name, optional mail and homepage attributes |
namespace | PascalCase, maps to OCA\{Namespace}\ PHP namespace |
category | One of: customization, files, games, integration, monitoring, multimedia, office, organization, security, social, tools |
dependencies/nextcloud | BOTH min-version AND max-version required |
info.xml Optional Fields
| Field | Purpose |
|---|
bugs | Issue tracker URL |
repository | Source code URL (with type attribute) |
website | Project homepage |
screenshot | App store screenshot (HTTPS required), optional small-thumbnail |
documentation | Child elements: user, admin, developer |
navigations/navigation | Top-level navigation entry |
background-jobs/job | Cron job class registrations |
repair-steps | Install/post-migration/uninstall repair steps |
commands/command | OCC CLI command registrations |
settings | Admin/personal settings page classes |
activity | Activity app integration (settings + providers) |
Deprecated info.xml Fields (NEVER Use)
These fields cause app store validation failure:
standalone, default_enable, shipped, public, remote, requiremin, requiremax
Namespace to File Path Mapping
info.xml <namespace> | PHP Class | File Path |
|---|
MyApp | OCA\MyApp\AppInfo\Application | lib/AppInfo/Application.php |
MyApp | OCA\MyApp\Controller\PageController | lib/Controller/PageController.php |
MyApp | OCA\MyApp\Service\ItemService | lib/Service/ItemService.php |
MyApp | OCA\MyApp\Db\ItemMapper | lib/Db/ItemMapper.php |
MyApp | OCA\MyApp\Listener\MyListener | lib/Listener/MyListener.php |
MyApp | OCA\MyApp\Migration\Version1000Date | lib/Migration/Version1000Date.php |
IBootstrap Lifecycle
| Phase | Method | When Called | Rules |
|---|
| 1 | register(IRegistrationContext $context) | Early, before all apps loaded | ONLY use $context API methods. NEVER query services. |
| 2 | boot(IBootContext $context) | After ALL apps completed register() | All services available. Use $context->injectFn() for DI. |
Valid Category Values
customization | files | games | integration | monitoring | multimedia | office | organization | security | social | tools
Critical Warnings
ALWAYS include <namespace> in info.xml -- the autoloader and DI container depend on it to map OCA\{Namespace}\* to the lib/ directory.
ALWAYS set both min-version and max-version in <dependencies><nextcloud> -- both are required for app store validation.
ALWAYS implement IBootstrap in Application.php for NC 28+ apps -- legacy constructor-based service resolution is deprecated.
ALWAYS use register() for event listeners, middleware, and service aliases -- these are lazily resolved.
ALWAYS place Application.php at lib/AppInfo/Application.php -- Nextcloud expects this exact path.
ALWAYS use the app.svg file in img/ as the app icon -- Nextcloud uses it automatically for navigation and favicons.
NEVER query services or resolve dependencies in register() -- other apps may not have completed their registration yet.
NEVER put business logic in Application.php -- keep it in Service/ classes. Application.php handles only registration and boot wiring.
NEVER use database.xml for new apps -- use PHP migration classes in lib/Migration/ instead.
NEVER use deprecated requiremin/requiremax -- use <dependencies><nextcloud min-version="" max-version=""/>.
NEVER include sensitive data (API keys, passwords) in info.xml -- it is publicly readable.
NEVER omit the id field or use characters other than lowercase ASCII and underscores.
Essential Patterns
Pattern 1: Minimal info.xml
<?xml version="1.0"?>
<info xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://apps.nextcloud.com/schema/apps/info.xsd">
<id>myapp</id>
<name>My Application</name>
<summary>Short description for app listing</summary>
<description>Full description with **Markdown** support</description>
<version>1.0.0</version>
<licence>AGPL-3.0-or-later</licence>
<author mail="dev@example.com">Developer Name</author>
<namespace>MyApp</namespace>
<category>tools</category>
<bugs>https://github.com/org/myapp/issues</bugs>
<dependencies>
<nextcloud min-version="28" max-version="32"/>
Pattern 2: Application.php with IBootstrap
<?php
declare(strict_types=1);
namespace OCA\MyApp\AppInfo;
use OCA\MyApp\Listener\UserDeletedListener;
use OCA\MyApp\Middleware\AuthMiddleware;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\User\Events\BeforeUserDeletedEvent;
class Application extends App implements IBootstrap {
public const APP_ID = 'myapp';
public function __construct() {
::(::);
}
{
->(
::,
::
);
->(::);
->(::, ::);
}
{
->(function (IFooManager ) {
->(::);
});
}
}
Pattern 3: Navigation Entry in info.xml
<navigations>
<navigation>
<name>My App</name>
<route>myapp.page.index</route>
<icon>app.svg</icon>
<order>10</order>
</navigation>
</navigations>
The route value uses the format {appid}.{controller}.{method} -- it MUST match a route defined in appinfo/routes.php.
Pattern 4: Minimal routes.php
<?php
return [
'routes' => [
['name' => 'page#index', 'url' => '/', 'verb' => 'GET'],
],
];
Pattern 5: Minimal PHP Template
<!-- templates/main.php -->
<?php
script('myapp', 'myapp-main');
style('myapp', 'style');
?>
<div id="app-content">
<div id="content"></div>
</div>
Pattern 6: App Generator
Use the official Nextcloud app generator to scaffold a new app:
URL: https://apps.nextcloud.com/developer/apps/generate
This generates a downloadable skeleton with correct directory structure, info.xml, Application.php, basic controller, routes, and build configuration. It does NOT publish to the app store.
Decision Tree: Starting a New App
Need a new Nextcloud app?
├── Use the app generator → https://apps.nextcloud.com/developer/apps/generate
│ └── Download and customize the skeleton
├── OR create manually:
│ ├── 1. Create appinfo/info.xml with ALL required fields
│ ├── 2. Create lib/AppInfo/Application.php implementing IBootstrap
│ ├── 3. Create appinfo/routes.php with at least one route
│ ├── 4. Create lib/Controller/ with your first controller
│ ├── 5. Create templates/main.php for the page template
│ └── 6. Place app.svg in img/ for the app icon
│
├── Need a navigation entry?
│ └── Add <navigations> to info.xml with route matching routes.php
│
├── Need background jobs?
│ └── Add <background-jobs> to info.xml + create Job class in lib/Cron/
│
├── Need database tables?
│ └── Create migration class in lib/Migration/ (NEVER use database.xml)
│
├── Need admin settings?
│ └── Add <settings> to info.xml + create Settings class in lib/Settings/
│
└── Need OCC commands?
└── Add <commands> to info.xml + create Command class in lib/Command/
Bootstrap Sequence (NC 28+)
- Nextcloud scans enabled apps for
lib/AppInfo/Application.php
- Apps implementing
IBootstrap have register() called (ordered by app dependencies)
- App load groups processed (filesystem, session, etc.) in priority order
- All
Application classes fully instantiated
- All
boot() methods called -- all prior registrations are guaranteed complete
- Request routing begins
Reference Links
Official Sources