Skip to content
Back to skills

Organize Project

ASecurity

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.

  • 128 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 26, 2026
ai-agentsjavascriptgojavasqlexpressapidatabase

Works with

  • cli
  • api
  • mcp

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add mendixlabs/mxcli --skill organize-project --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Organize Project?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Organize Project
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mendixlabs-organize-project/badge)](https://www.skillsdirectory.com/skills/mendixlabs-organize-project)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: organize-project
description: "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."
---

# Project Organization: Folders and Moving Documents

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`:

```mdl
mdl 1;
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:

```sql
mdl 1;
create page MyModule.Customer_Overview folder 'Customer'
(
  title: 'Customer Overview',
  layout: Atlas_Core.Atlas_Default
)
{
  -- widgets
};
```

### Snippets

```sql
mdl 1;
create snippet MyModule.CustomerCard folder 'Customer'
{
  -- widgets
};
```

### Nested Folders

Use `/` to create nested folder paths. Missing folders are created automatically:

```mdl
mdl 1;
-- 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.

```sql
-- 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 `describe 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)

```mdl
mdl 1;
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)

```mdl
mdl 1;
move page MyModule.CustomerEdit to MyModule;
```

### Move Across Modules

```mdl
mdl 1;
-- 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:**

```mdl
mdl 1;
list 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`, `task 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 | `consumed rest service`, `published rest service`, `consumed odata service`, `published 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 task 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 |

```mdl
mdl 1;
create import mapping CRM.IMM_Order folder 'Private/Import mappings'
  with json structure CRM.JSON_Order { create CRM.Order { Id = id } };

create task 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

```mdl
mdl 1;
-- 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
list impact of CRM.Header_Snippet;
move snippet CRM.Header_Snippet to folder 'Shared' in Common;

-- Move entity to different module
list 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`.

```sql
mdl 1;
-- 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.

```sql
mdl 1;
-- 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 `list impact of` first
- [ ] Folder naming is consistent across modules
- [ ] DROP FOLDER: verify folder is empty before dropping
- [ ] After a batch of moves: `list folders in MyModule` to confirm the layout

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…