Project Organization: Folders and Moving Documents
SkillDocs & knowledgeLets your agent organise project documents into folders and move them between folders and modules.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Project Organization: Folders and Moving Documents skill
About this capability
Organise documents into folders and move them between folders and modules with MOVE. Use when a module has grown unstructured, when restructuring a project, or when a document is in the wrong place.
What this skill tells your AI
The instructions your AI receives, as published by mendixlabs/mxcli in .claude/skills/mendix/organize-project/SKILL.md and read by ahel’s review.
This skill covers organizing Mendix project documents (pages, microflows, snippets, nanoflows) into folders and moving them between folders and modules.
When to Use This Skill
Use this skill when:
- Organizing documents into folder hierarchies within a module
- Moving documents between folders
- Moving documents between modules
- Restructuring a project for better maintainability
- Setting up folder conventions for a new module
Folder Conventions
Organize by functional grouping — keep all artifacts for a feature together, not separated by document type. This way, a developer working on "Customer" finds everything in one place: pages, microflows, snippets, and validation logic.
Recommended folder structure within a module:
CRM/
├── Customer/
│ ├── Customer_Overview -- Overview page
│ ├── Customer_NewEdit -- Edit page
│ ├── CustomerCard -- Snippet
│ ├── ACT_Customer_Save -- Save microflow
│ ├── ACT_Customer_Delete -- Delete microflow
│ ├── ACT_Customer_New -- New microflow
│ ├── VAL_Customer -- Validation microflow
│ └── DS_Customer_Filter -- Data source microflow
├── Order/
│ ├── Order_Overview
│ ├── Order_NewEdit
│ ├── ACT_Order_Save
│ └── VAL_Order
└── Shared/ -- Cross-cutting concerns
├── SUB_SendNotification
└── Navigation_Snippet
Why functional grouping over type grouping:
- All related artifacts are in one place — easier to navigate and review
- Adding or removing a feature is a single folder operation
- Naming prefixes (ACT_, VAL_, SUB_, DS_) already indicate document type
- Mirrors how developers think: "I'm working on Customer" not "I'm working on microflows"
Adapt to your project's conventions. The key is consistency across modules.
Creating Documents in Folders
Microflows
Use the folder keyword after the return type, before begin:
create microflow MyModule.ACT_ProcessOrder ($Order: MyModule.Order)
returns boolean as $success
folder 'Order'
begin
commit $Order;
return true;
end;
Pages
Use the folder property inside the page properties:
create page MyModule.Customer_Overview
(
title: 'Customer Overview',
layout: Atlas_Core.Atlas_Default,
folder: 'Customer'
)
{
-- widgets
}
Snippets
create snippet MyModule.CustomerCard
(
folder: 'Customer'
)
{
-- widgets
}
Nested Folders
Use / to create nested folder paths. Missing folders are created automatically:
-- Creates 'Order', then 'Order/Batch' if they don't exist
create microflow MyModule.ACT_BatchProcess ($list: list of MyModule.Order)
folder 'Order/Batch'
begin
loop $Order in $list begin
commit $Order;
end loop;
return;
end;
Reading the Layout Back
list folders shows the folder layout of a module and what is in each folder.
This is the counterpart to move: move puts a document somewhere, list folders shows where everything actually is.
-- One module
list folders in MyModule;
-- Every module in the project
list folders;
MyModule
(module root) [1]
Microflow ACT_Unfiled
Api [0]
Api/Published [1]
ODataService PublicApi
Support [1]
JavaAction Helper
(3 folder(s), 3 document(s))
Three things about the output are deliberate:
- Empty folders are listed (
Api [0]), so the listing is the whole layout and can be diffed against an intended one. - Documents still at the module root appear under
(module root)— what is not filed yet is the thing you most want to notice. - Ordering is stable, so a diff between two runs shows only real movement.
Use the CLI's --json flag for a row per document (Module, Folder, Kind, Document)
when comparing against a checked-in layout.
Do not reach for show structure here: it groups by document type at every
depth and never shows which folder a document sits in.
Moving Documents
The move command relocates existing documents between folders and modules.
Move to a Folder (Same Module)
move page MyModule.CustomerEdit to folder 'Customer';
move microflow MyModule.ACT_ProcessOrder to folder 'Order';
move snippet MyModule.NavigationMenu to folder 'Shared';
move nanoflow MyModule.NAV_OpenCustomer to folder 'Customer';
move enumeration MyModule.OrderStatus to folder 'Shared';
Move to Module Root (Out of Folder)
move page MyModule.CustomerEdit to MyModule;
Move Across Modules
-- Move to another module's root
move page OldModule.CustomerPage to NewModule;
-- Move to a folder in another module
move page OldModule.CustomerPage to folder 'Pages' in NewModule;
Cross-Module Move Warning
Cross-module moves change the qualified name (e.g., OldModule.CustomerPage becomes NewModule.CustomerPage). This breaks by-name references such as:
- Microflows calling
show page OldModule.CustomerPage - Other microflows calling
call microflow OldModule.SomeMicroflow - Widget actions referencing the old qualified name
Always check impact before cross-module moves:
show impact of OldModule.CustomerPage;
-- Review the output, then move if safe:
move page OldModule.CustomerPage to NewModule;
Folder Rules
- Folder names are case-sensitive
- Use
/as separator for nested folders:'Parent/Child/Grandchild' - Folders are created automatically if they don't exist
- Moving to a folder that doesn't exist creates it
- Empty folders are preserved in the project
Supported Document Types
move accepts every top-level document type, spelled the way describe
spells it:
| Group | Types |
|---|---|
| Pages | page, snippet, building block, layout, menu |
| Logic | microflow, nanoflow, workflow, queue, scheduled event |
| Domain | enumeration, constant, regular expression |
| Mappings | json structure, import mapping, export mapping |
| Code | java action, javascript action, database connection, data transformer |
| Resources | image collection, icon collection |
| Integration | rest client, published rest service, odata client, odata service, business event service |
| AI | model, agent, knowledge base, consumed mcp service |
move entity is the exception: an entity lives inside a domain model, so it
moves between modules only, never into a folder.
If the named document turns out to be a different type, the statement is refused
and the error names what it really is — move queue Mod.JSON_Order reports that
Mod.JSON_Order is a json structure.
FOLDER on Create
Every document type takes a folder clause on create, so a document can be
placed in the statement that creates it rather than in a separate move. Where
the clause goes depends on the statement's shape:
| Document Type | FOLDER on Create |
|---|---|
| Page, Snippet | folder: 'path' — a property, inside the parentheses |
| Microflow, Nanoflow | folder 'path' — a keyword, before begin |
| Enumeration, Constant | folder 'path' — a keyword, after the definition |
| Everything else | folder 'path' — a keyword, straight after the qualified name |
create import mapping CRM.IMM_Order folder 'Private/Import mappings'
with json structure CRM.JSON_Order { create CRM.Order { Id = id } };
create queue CRM.Q_Orders folder 'Private/Queues' ( Parallelism: 3 );
create java action CRM.JA_Sync folder 'Private/Java' () returns string
as $$return null;$$;
A folder clause on create or modify moves an existing document. It used to
be silently ignored: the statement reported success, the folder was created, and
the document stayed where it was (#932). Omitting the clause leaves placement
alone — it never returns a document to the module root — so adding a folder to a
script is safe and removing it is a no-op.
describe emits the clause, so a description replays into the same folder
rather than into the module root.
Example: Reorganize a Module
-- Group all Customer artifacts together
move page CRM.Customer_Overview to folder 'Customer';
move page CRM.Customer_NewEdit to folder 'Customer';
move microflow CRM.ACT_Customer_Save to folder 'Customer';
move microflow CRM.ACT_Customer_Delete to folder 'Customer';
move microflow CRM.ACT_Customer_New to folder 'Customer';
move microflow CRM.VAL_Customer to folder 'Customer';
move snippet CRM.CustomerCard to folder 'Customer';
-- Group all Order artifacts together
move page CRM.Order_Overview to folder 'Order';
move page CRM.Order_NewEdit to folder 'Order';
move microflow CRM.ACT_Order_Save to folder 'Order';
move microflow CRM.ACT_Order_Process to folder 'Order/Processing';
-- Move shared artifacts to a Shared folder or common module
show impact of CRM.Header_Snippet;
move snippet CRM.Header_Snippet to folder 'Shared' in Common;
-- Move entity to different module
show impact of CRM.Customer;
move entity CRM.Customer to CustomerModule;
-- Move enumeration to different module
move enumeration CRM.OrderStatus to SharedModule;
Moving Folders
Use move folder to reorganize folders. Syntax matches document moves: Module.FolderName.
-- Move a folder into another folder
move folder MyModule.Resources to folder 'Archive';
-- Move a nested folder (use double quotes for paths with /)
move folder MyModule."Orders/Archive" to MyModule;
-- Move a folder to a different module
move folder MyModule.SharedWidgets to CommonModule;
-- Move a folder into a folder in another module
move folder MyModule.Templates to folder 'Shared' in CommonModule;
Deleting Folders
Use drop folder to remove empty folders. The folder must not contain any documents or sub-folders.
-- Drop an empty folder
drop folder 'OldPages' in MyModule;
-- Drop a nested folder (only the leaf is removed)
drop folder 'Orders/Archive' in MyModule;
-- Move contents out first, then drop
move microflow MyModule.ACT_Process to MyModule;
drop folder 'Processing' in MyModule;
Validation Checklist
- Folder paths use
/separator (not\) - FOLDER keyword placement is correct (before BEGIN for microflows, inside properties for pages)
- Cross-module moves: checked impact with
show impact offirst - Folder naming is consistent across modules
- DROP FOLDER: verify folder is empty before dropping
- After a batch of moves:
list folders in MyModuleto confirm the layout
Signals
- GitHub stars
- 122
- Forks
- 49
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
organize-project- Source
- github.com/mendixlabs/mxcli