# How to Configure the Astryx CLI Using astryx.config.mjs for Custom Templates

> Learn to configure Astryx CLI using astryx.config.mjs. Set up custom templates with integrations and local layout components. Customize your project workflow now.

- Repository: [Meta/astryx](https://github.com/facebook/astryx)
- Tags: how-to-guide
- Published: 2026-07-02

---

**You configure the Astryx CLI by creating an `astryx.config.mjs` file at your project root that exports a default object containing an `integrations` array for external template packages and an optional `experimental.xle.components` map for local layout components.**

The Astryx CLI from the `facebook/astryx` repository discovers custom templates and components by loading a single configuration file located next to your [`package.json`](https://github.com/facebook/astryx/blob/main/package.json). This file uses a schema defined in `packages/cli/src/lib/config-schema.mjs` to validate settings before the CLI executes commands like `astryx template --list` or processes layout expressions.

## Creating the astryx.config.mjs File

Place `astryx.config.mjs` at your repository root. It must **export a default plain object** that conforms to the Zod schema in `packages/cli/src/lib/config-schema.mjs`【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/lib/config-schema.mjs#L26-L48】.

The CLI validates this file during `Project.load()`, throwing clear schema errors if the shape is incorrect【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/lib/config-schema.mjs#L81-L88】.

```javascript
// astryx.config.mjs
export default {
  integrations: ["my-company-astryx-integration"],
  issuesUrl: "https://github.com/my-org/my-repo/issues",
  experimental: {
    xle: {
      components: {
        MyCard: {
          from: "@/components/MyCard",
          description: "A custom card component for dashboards",
          default: true,
        },
      },
    },
  },
};

```

**Key configuration keys:**

- **`integrations`**: Array of npm package names that expose templates via their own `astryx.templates` field.
- **`experimental.xle.components`**: Map of component names to import metadata for use in XLE layout expressions.
- **`issuesUrl`**: Optional URL displayed by `astryx doctor`.

## Registering Integration Packages for External Templates

To share reusable templates across projects, publish an npm package containing a `templates` directory and declare it in [`package.json`](https://github.com/facebook/astryx/blob/main/package.json):

```json
{
  "name": "my-company-astryx-integration",
  "version": "1.0.0",
  "astryx": {
    "templates": "./templates"
  }
}

```

The CLI discovers these templates through `discoverIntegrationTemplates` in `packages/cli/src/api/template.mjs`【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/api/template.mjs#L84-L92】, which reads the `astryx.templates` field from each package listed in your `integrations` array.

**Required template structure:**

```

templates/
 ├─ pages/
 │   └─ Dashboard/
 │       ├─ template.doc.mjs   // Metadata exporting a `doc` object
 │       └─ page.tsx           // Component implementation
 └─ blocks/
     └─ KPI/
         ├─ kpi.doc.mjs
         └─ kpi.tsx

```

The **doc file** must export a `doc` object satisfying `TemplateEnvelopeSchema`, while the **source file** contains the actual TSX component. The CLI scans these directories via `discoverIntegrationTemplatesForOne`【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/api/template.mjs#L94-L103】.

## Exposing Local XLE Components

Register local components for use in XLE (XML Layout Expression) strings by adding them to `experimental.xle.components`. The layout engine in `packages/cli/src/api/layout.mjs` consumes these entries when expanding expressions like `{my-card}` into imports【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/api/layout.mjs#L46-L52】.

```javascript
experimental: {
  xle: {
    components: {
      MyCard: {
        from: "@/components/MyCard",  // Import path relative to project root
        description: "Card component for XLE",
        default: true,                // Import as default export
      },
    },
  },
}

```

Now you can write layout expressions such as `A[cp6] > L > {my-card} > T`, and the generated code will automatically import and render `<MyCard />`.

## Working with Custom Templates via the CLI

Once configured, interact with your templates using the `astryx template` command:

1. **List available templates** (core + integrations):
   ```bash
   npx astryx template --list
   ```

2. **Inspect a template**:
   ```bash
   npx astryx template Dashboard --show
   ```

3. **Generate a skeleton**:
   ```bash
   npx astryx template Dashboard --skeleton
   ```

4. **Copy to your project**:
   ```bash
   npx astryx template Dashboard --target src/pages/Dashboard.tsx
   ```

**Behind the scenes**, the `template` command calls `discoverAll` to aggregate core, external, and integration templates【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/api/template.mjs#L16-L24】, then applies `stripTemplateAssetRefs` to remove Meta-specific image URLs before writing files【/cache/repos/github.com/facebook/astryx/main/packages/cli/src/api/template.mjs#L51-L57】.

## Complete Configuration Example

Below is a minimal, production-ready setup combining external integrations and local XLE components.

**astryx.config.mjs:**

```javascript
export default {
  integrations: ["@company/astryx-templates"],
  experimental: {
    xle: {
      components: {
        DataGrid: {
          from: "@/components/DataGrid",
          description: "Advanced data table for analytics",
          default: false,
        },
      },
    },
  },
};

```

**Integration package structure:**

```json
// node_modules/@company/astryx-templates/package.json
{
  "name": "@company/astryx-templates",
  "astryx": {
    "templates": "./templates"
  }
}

```

**Template metadata (templates/pages/Analytics/template.doc.mjs):**

```javascript
export const doc = {
  type: "page",
  name: "Analytics",
  description: "Data visualization starter",
  category: "Dashboards",
  componentsUsed: ["DataGrid"],
};

```

## Summary

- **Create `astryx.config.mjs`** at your project root exporting a default object validated against the schema in `packages/cli/src/lib/config-schema.mjs`.
- **Add integration packages** to the `integrations` array to import external templates discovered via `discoverIntegrationTemplates` in `packages/cli/src/api/template.mjs`.
- **Register XLE components** under `experimental.xle.components` to use custom components in layout expressions processed by `packages/cli/src/api/layout.mjs`.
- **Use CLI commands** like `astryx template --list` and `--target` to inspect and scaffold templates from integrated packages.

## Frequently Asked Questions

### What file format does astryx.config.mjs use?

The configuration file must be an ES module (`.mjs`) that exports a default JavaScript object. The CLI explicitly validates this object against a Zod schema defined in `packages/cli/src/lib/config-schema.mjs`, ensuring type safety for fields like `integrations` and `experimental.xle.components`.

### How do I share templates across multiple projects?

Publish an npm package containing your templates in a dedicated directory, add an `astryx.templates` field to its [`package.json`](https://github.com/facebook/astryx/blob/main/package.json) pointing to that directory, and list the package name in the `integrations` array of each project's `astryx.config.mjs`. The CLI automatically discovers these via `discoverIntegrationTemplatesForOne` in `packages/cli/src/api/template.mjs`.

### What is the difference between integrations and experimental.xle.components?

**Integrations** are external npm packages that provide reusable page and block templates (physical `.tsx` files you can scaffold). **Experimental XLE components** are local React components registered for use inside layout expression strings (e.g., `{my-component}`), allowing dynamic composition without scaffolding files.

### How does the CLI validate the configuration?

During initialization, the `Project.load()` method reads `astryx.config.mjs` and validates it against the schema in `packages/cli/src/lib/config-schema.mjs` using Zod. If the configuration object is malformed, the CLI throws a descriptive error before executing any commands, preventing runtime failures from invalid template paths or component definitions.