Skip to content
Concept

App Package structure

Find the file to change for an App feature and understand which identifiers belong to its public contract.

App Package structure

Find the file to change

An App is one independent repository and Composer release. After Create an App Package and Create a Resource, use this map to find the owner of a change. Paths below are relative to the App root.

ChangeFile or directory
Package identity and dependency rangescomposer.json
Frontend peer dependencies and App aliasespackage.json
Discovery locations and migration pathssrc/WorkshopAppManifest.php
Persistent fieldsdatabase/migrations/tenant/ and src/Models/Note.php
Validation and API responsessrc/Http/Controllers/NoteController.php
Record authorizationsrc/Policies/NotePolicy.php
Resource identity, descriptor, permissions, menusrc/Contribution/Resources/NoteModule.php
API routesroutes/routes.php
Resource types and route helpersresources/js/resources/notes/note-resource-contract.ts
Shared detail/form field presentationresources/js/resources/notes/note-information-schema.tsx
Page state and data fetchingresources/js/resources/notes/surface/
List, form, and detail compositionresources/js/resources/notes/section/
Frontend registrationresources/js/index.ts
Labelsresources/lang/{locale}.json
Regression coveragetests/ and frontend tests

This is the Workshop/Note generated layout, not a claim that every existing App uses identical internal composition. The generator source is app/Console/Commands/MakePackageResource.php and stubs/package-resource/.

Make one change across its owners

Adding a field usually changes persistence, validation, response types, and presentation. Declaring it in a descriptor alone does not implement storage or form handling. Follow Data Model and Migrations, then Build an App screen.

Keep private helpers beside their App feature. A capability belongs in the SDK only when it expresses a durable platform responsibility, not just because two Apps happen to need similar code. For another App's data, use Choose a cross-App integration.

Identity and discovery

IdentifierWhat depends on it
Composer package nameDependency selection and release installation
app_keyApp identity, route and permission namespaces
app_table_prefixApp-owned table names
Resource keyCatalog, permissions, references, and descriptors
Descriptor or event keyPublished configuration and runtime consumers

Treat public keys as compatibility contracts. A label can change without renaming its key. A table prefix or Resource key change needs an explicit migration and consumer plan; it is not a routine refactor.

Manifest-declared contribution locations determine discovery. Putting a class in any arbitrary folder is insufficient. The generator prepares these locations; see Extension Model before introducing another contribution. The exact metadata contract is in App manifest.

Local source and installed packages

Local setup can mount a selected App checkout under packages/. That is an editing arrangement. CI and released hosts may install the same package under vendor/ from Composer. Your runtime code must work with either installation. Use manifest-relative paths or the SDK's supported metadata; never reconstruct a Core package path. Do not edit vendor/.

All package files ship together: PHP, frontend, translations, and migrations. Release an App explains version selection and host installation. A source checkout existing on disk does not prove that Composer is currently using it.

Source of truth: docs/developers/content/en/architecture/package-anatomy.md