Imported from paialex/ai-skills-bank (
skills/aem-architect/SKILL.md). Install upstream withnpx skills add paialex/ai-skills-bank --skill aem-architect. Copyright stays with the author.
AEM Architect Skill
Enterprise-grade AEM solution design and implementation guidance.
Workflow Routing
Route to the appropriate workflow based on the request:
| Request Type | Workflow | Use When |
|---|---|---|
| Diagrams/Visualizations | workflows/AEMDiagrams.md | Architecture diagrams, flowcharts, sequence diagrams, ASCII art |
| Component Development | Main workflow below | Building new components, dialogs, HTL |
| Service/Backend | Main workflow below | OSGi services, Sling Models, servlets |
| Infrastructure | Main workflow below | Dispatcher, caching, CI/CD |
Diagram Request Detection
Use the AEMDiagrams workflow when the user mentions:
- "diagram", "flowchart", "sequence diagram", "architecture diagram"
- "visualize", "draw", "show me", "illustrate"
- "mermaid", "ASCII art", "box diagram"
- "component structure", "request flow", "cache flow"
- "service dependencies", "class diagram", "state diagram"
Main Workflow
Follow this structured workflow for every AEM implementation request:
Phase 1: Requirements Gathering
Step 1.1: Ask for User Preference
First, ask the user:
"Would you like me to ask you some discovery questions to provide a more precise and tailored solution?
- Yes - I'll ask targeted questions about your requirements
- No - I'll proceed autonomously based on best practices and available context"
Step 1.2: Check for Attached Requirements
If the user has attached a file (.txt, .doc, .docx, or .md):
- Read and analyze the file for requirements
- Extract answers to the discovery questions below from the document
- If user accepted questions in Step 1.1, ask additional precision questions for any gaps or ambiguities found
Step 1.3: Discovery Questions (if user accepted)
Ask relevant questions from these categories:
Component Architecture
- Component type? (content, structural, container, navigation)
- Extend AEM Core Components or fully custom?
- Required dialog fields? (text, image, pathfield, multifield, nested)
- Target environment? (author, publish, or both)
Performance & Caching
- Expected traffic volume? (low, medium, high, enterprise-scale)
- Caching strategy? (aggressive, moderate, dynamic)
- CDN integration required?
Integration
- Headless/hybrid JSON APIs required?
- External service integrations?
- GraphQL for Content Fragments?
- SPA framework integration?
Phase 2: Analysis & Planning
Step 2.1: Present High-Level Overview
After gathering requirements (or analyzing autonomously), present:
Understanding Summary
Based on my analysis, here's what I understand about your requirements:
- [Bullet points summarizing the project scope]
- [Target environment and architecture]
- [Key components and features needed]
- [Performance and caching considerations]
- [Integration points]
Step 2.2: Present TODO List
Create and present a numbered task list:
Implementation Plan
I will implement the following tasks:
- Task 1: Description
- Task 2: Description
- Task 3: Description ...
Would you like to proceed with this plan, or do you have any changes to propose?
Step 2.3: Wait for User Approval
- If user approves → Proceed to Phase 3
- If user proposes changes → Update the plan and present again
- Do NOT start implementation until user confirms
Phase 3: Implementation
Execute the approved TODO list:
- Create component structure
- Implement Sling Model with proper injectors
- Design dialog using Granite UI patterns
- Configure ClientLibs with bundling strategy
- Set up Dispatcher rules
- Provide testing guidance
Phase 4: Validation
Present completed work with:
- Summary of what was implemented
- File locations and structure
- Testing recommendations
- Cloud Manager quality gate considerations
Reference Documentation
Read the appropriate reference based on the task:
Workflows
| Workflow | File | Use When |
|---|---|---|
| AEM Diagrams | workflows/AEMDiagrams.md | Creating Mermaid or ASCII architecture diagrams |
Core References (in this skill)
| Topic | File | Use When |
|---|---|---|
| Architecture Patterns | references/architecture-deep-dive.md | Designing system architecture, scaling, MVC patterns |
| Cloud Service | references/cloud-service-guidelines.md | Developing for AEMaaCS, cluster-aware code, state management |
| Dialog Fields | references/dialog-field-types.md | Creating component dialogs with Granite UI |
| Dispatcher | references/dispatcher-configuration.md | Configuring filters, caching, load balancing |
| Performance | references/performance-optimization.md | Optimizing ClientLibs, Sling Models, caching |
| Sling Jobs | references/sling-jobs.md | Background task scheduling for Cloud Service |
| Testing Patterns | references/testing-patterns.md | Unit testing with AEM Mocks, JUnit 5 |
| Anti-Patterns | references/anti-patterns.md | Common mistakes and how to fix them |
| Code Snippets | references/code-snippets.md | Copy-paste ready code templates |
External Guides (in project root)
| Topic | File | Use When |
|---|---|---|
| Sling Models | aem-sling-models-guide.md | Model patterns, injectors, exporters |
| OSGi Services | aem-osgi-services-guide.md | Service design, dependency injection |
| Servlets | aem-servlets-guide.md | Endpoint patterns, security |
| Dialogs | aem-dialog-creation-guide.md | Granite UI, multifields, validation |
| ClientLibs | aem-clientlibs-guide.md | JS/CSS bundling, lazy loading |
| Dispatcher | aem-dispatcher-guide.md | Detailed cache configuration |
| Components | component-development.md | HTL, component structure |
| Best Practices | adobe-technical-practices.md | Adobe-recommended patterns |
Quick Reference: Component Creation
Component Structure
/apps/myproject/components/mycomponent/
├── .content.xml # Component definition
├── _cq_dialog/.content.xml # Author dialog
├── _cq_editConfig.xml # Edit configuration
├── mycomponent.html # HTL template
└── clientlib/ # Component CSS/JS
Component Definition
<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:jcr="http://www.jcp.org/jcr/1.0"
xmlns:cq="http://www.day.com/jcr/cq/1.0"
xmlns:sling="http://sling.apache.org/jcr/sling/1.0"
jcr:primaryType="cq:Component"
jcr:title="My Component"
jcr:description="Description"
componentGroup="My Project - Content"
sling:resourceSuperType="core/wcm/components/title/v3/title"/>
Sling Model Pattern
@Model(
adaptables = {Resource.class, SlingHttpServletRequest.class},
adapters = {MyComponent.class, ComponentExporter.class},
resourceType = MyComponentImpl.RESOURCE_TYPE,
defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME,
extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class MyComponentImpl implements MyComponent {
static final String RESOURCE_TYPE = "myproject/components/mycomponent";
@ValueMapValue
private String title;
@OSGiService
private MyService myService;
@Override
public String getTitle() { return title; }
}
Common Dialog Fields
| Field | Resource Type |
|---|---|
| Text | granite/ui/components/coral/foundation/form/textfield |
| Textarea | granite/ui/components/coral/foundation/form/textarea |
| Rich Text | cq/gui/components/authoring/dialog/richtext |
| Checkbox | granite/ui/components/coral/foundation/form/checkbox |
| Select | granite/ui/components/coral/foundation/form/select |
| Path | granite/ui/components/coral/foundation/form/pathfield |
| Image | cq/gui/components/authoring/dialog/fileupload |
| Multifield | granite/ui/components/coral/foundation/form/multifield |
For complete field examples, see references/dialog-field-types.md.
Caching Decision Tree
Is content personalized?
├── YES → No Dispatcher cache
│ └── Use client-side personalization or ESI
└── NO → Cache at Dispatcher
├── Static asset (JS/CSS/images)?
│ └── Long TTL (1 year) + content-hash
├── HTML content?
│ └── Moderate TTL (5-60 min) + statfileslevel
└── API/JSON?
├── Public → TTL based on freshness needs
└── Private → No Dispatcher cache
Statfileslevel Reference
| Structure | Level | Effect |
|---|---|---|
/content/site |
2 | Per-site invalidation |
/content/site/language |
3 | Per-language invalidation |
/content/site/region/country |
4 | Per-country invalidation |
Security Checklist
Dispatcher Filters (Default Deny)
/filter {
/0001 { /type "deny" /glob "*" }
/0100 { /type "allow" /method "GET" /url "/content/mysite/*" }
/0200 { /type "allow" /method "GET" /url "/etc.clientlibs/*" }
/0300 { /type "allow" /method "GET" /url "/content/dam/*" }
/0900 { /type "deny" /url "/bin/*" }
/0901 { /type "deny" /url "/system/*" }
/0902 { /type "deny" /url "*.infinity.json" }
}
Service User Pattern
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
Map.of(ResourceResolverFactory.SUBSERVICE, "myproject-service-user"))) {
// Minimal permissions operations
}
Cloud Service Specifics
When developing for AEMaaCS, always read references/cloud-service-guidelines.md for:
- Cluster-aware code: Instances can stop anytime
- No local state: Disk is ephemeral
- Sling Jobs: For reliable background tasks
- HTTP timeouts: Always set connect/read timeouts
- Rate limiting: Handle 429 with exponential backoff
- Touch UI only: No Classic UI support
- Immutable repository:
/libsand/appsare read-only
CI/CD Quality Gates
| Gate | Checks | Action |
|---|---|---|
| Code Quality | SonarQube, code smells | Fix before merge |
| Security | Vulnerability scan | Immediate fix |
| Performance | Load test, response times | Review if fails |
Common Pitfalls
- JCR queries in render path → Use content hierarchy traversal
- Hardcoded paths → Use context-aware configuration
- Unclosed ResourceResolvers → Use try-with-resources
- Deep multifield nesting → Consider child nodes
- Missing Dispatcher filters → Default-deny approach
- Admin sessions in code → Use service users
- Untested cache invalidation → Verify statfileslevel
- Large inline dependencies → Lazy load heavy scripts
- Skipping Core Components → Extend before building custom
- Ignoring Cloud Manager gates → Fix locally first