> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/meteor/meteor/llms.txt
> Use this file to discover all available pages before exploring further.

# Meteor Project Structure

> Understanding how Meteor organizes files, loads code, and structures applications

## Directory Structure

Meteor uses a convention-based file structure that determines where code runs and how it's loaded.

### Standard Layout

A typical Meteor project follows this organization:

```bash theme={null}
my-app/
├── client/              # Client-only code (browser)
│   ├── main.js         # Client entry point
│   └── main.html       # HTML templates
├── server/              # Server-only code (Node.js)
│   └── main.js         # Server entry point
├── imports/             # Lazy-loaded modules
│   ├── api/            # Collections, methods, publications
│   ├── ui/             # React/Blaze/Vue components
│   └── startup/        # Initialization code
├── public/              # Static assets (served as-is)
│   ├── images/
│   └── fonts/
├── private/             # Server-only assets
├── tests/               # Test files
├── .meteor/             # Meteor configuration
│   ├── packages        # Package dependencies
│   ├── versions        # Locked package versions
│   └── release         # Meteor version
├── package.json         # npm dependencies
└── package-lock.json    # Locked npm versions
```

## Load Order Rules

Meteor loads files in a specific order based on their location:

### 1. Special Directories

<AccordionGroup>
  <Accordion title="client/ - Browser Only">
    Files in `client/` run only in the browser. Meteor automatically excludes this code from the server bundle.

    ```javascript client/main.js theme={null}
    // This code runs only in the browser
    import { Meteor } from 'meteor/meteor';
    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import App from '/imports/ui/App';

    Meteor.startup(() => {
      const root = createRoot(document.getElementById('root'));
      root.render(<App />);
    });
    ```
  </Accordion>

  <Accordion title="server/ - Server Only">
    Files in `server/` run only on the server (Node.js). This is where you put sensitive logic, API keys, and database operations.

    ```javascript server/main.js theme={null}
    // This code runs only on the server
    import { Meteor } from 'meteor/meteor';
    import '/imports/api/tasks';

    Meteor.startup(() => {
      // Server initialization
      console.log('Server started');
    });
    ```
  </Accordion>

  <Accordion title="imports/ - Lazy Loading">
    Files in `imports/` are not loaded automatically. You must explicitly import them. This enables code splitting and lazy loading.

    ```javascript imports/api/tasks.js theme={null}
    // Not loaded until explicitly imported
    import { Mongo } from 'meteor/mongo';
    import { Meteor } from 'meteor/meteor';

    export const Tasks = new Mongo.Collection('tasks');

    if (Meteor.isServer) {
      Meteor.publish('tasks', function() {
        return Tasks.find();
      });
    }
    ```
  </Accordion>

  <Accordion title="public/ - Static Assets">
    Files in `public/` are served as static assets. They're accessible at the root URL.

    ```
    public/images/logo.png → http://localhost:3000/images/logo.png
    ```
  </Accordion>

  <Accordion title="private/ - Server Assets">
    Files in `private/` are accessible only to server code via the `Assets` API.

    ```javascript theme={null}
    const data = Assets.getText('config.json');
    const binary = Assets.getBinary('image.png');
    ```
  </Accordion>

  <Accordion title="tests/ - Test Files">
    Files matching `*.test.js`, `*.tests.js`, or inside `tests/` are excluded from production builds.

    ```javascript tasks.test.js theme={null}
    import { Meteor } from 'meteor/meteor';
    import { assert } from 'chai';
    import { Tasks } from './tasks.js';

    if (Meteor.isServer) {
      describe('Tasks', () => {
        it('can be created', () => {
          const taskId = Tasks.insert({ text: 'Test task' });
          assert.ok(taskId);
        });
      });
    }
    ```
  </Accordion>
</AccordionGroup>

### 2. Load Priority

Within each directory, files load in this order:

1. Files in subdirectories load before files in parent directories
2. Files are sorted alphabetically by name
3. `main.*` files load last
4. Files in `lib/` directories load first

<Warning>
  Don't rely on load order. Use explicit imports instead. Load order is a legacy feature maintained for backwards compatibility.
</Warning>

## File Architecture Patterns

### Module Pattern (Recommended)

Use the `imports/` directory with explicit imports:

```javascript theme={null}
// imports/api/collections/Tasks.js
import { Mongo } from 'meteor/mongo';
export const Tasks = new Mongo.Collection('tasks');

// imports/api/methods/tasks.js
import { Meteor } from 'meteor/meteor';
import { Tasks } from '../collections/Tasks';

Meteor.methods({
  'tasks.insert'(text) {
    return Tasks.insert({ text, createdAt: new Date() });
  }
});

// server/main.js
import '/imports/api/methods/tasks';
import '/imports/api/publications/tasks';
```

### Split by Feature

Organize code by feature rather than by type:

```bash theme={null}
imports/
├── features/
│   ├── tasks/
│   │   ├── api/
│   │   │   ├── collection.js
│   │   │   ├── methods.js
│   │   │   └── publications.js
│   │   ├── ui/
│   │   │   ├── TaskList.jsx
│   │   │   └── TaskItem.jsx
│   │   └── index.js
│   └── users/
│       ├── api/
│       └── ui/
```

## The .meteor Directory

The `.meteor/` directory contains Meteor-specific configuration:

### packages

Lists Meteor packages used by your app:

```bash theme={null}
# Meteor packages used by this project, one per line.
meteor-base@1.5.2
mobile-experience@1.1.1
mongo@2.0.0
reactive-var@1.0.13
tracker@1.3.4
ecmascript@0.17.0
```

### versions

Locks exact package versions (like `package-lock.json` for npm):

```bash theme={null}
allow-deny@1.1.1
autoupdate@2.0.0
babel-compiler@7.11.3
base64@1.0.13
...
```

### release

Specifies the Meteor version:

```bash theme={null}
METEOR@3.2.2
```

<Tip>
  Commit `.meteor/packages` and `.meteor/release` to version control, but you can ignore `.meteor/versions` if using npm packages exclusively.
</Tip>

## Build Output Structure

When you build a Meteor app, it generates a "star" archive with this structure:

### Star Archive Layout

```bash theme={null}
output/
└── bundle/
    ├── star.json           # Build metadata
    ├── README              # Deployment instructions
    ├── main.js             # Node.js entry point
    └── programs/
        ├── server/         # Server program
        │   ├── program.json
        │   ├── server.js
        │   ├── npm/
        │   └── assets/
        └── web.browser/    # Client program
            ├── program.json
            ├── index.html
            └── app/
```

### star.json

Describes the build output:

```json theme={null}
{
  "format": "site-archive-pre1",
  "builtBy": "Meteor 3.2.2",
  "programs": [
    {
      "name": "web.browser",
      "arch": "web.browser",
      "path": "programs/web.browser"
    },
    {
      "name": "server",
      "arch": "os.linux.x86_64",
      "path": "programs/server"
    }
  ],
  "meteorRelease": "METEOR@3.2.2"
}
```

### program.json

Each program has a `program.json` describing its resources:

**Web Program:**

```json theme={null}
{
  "format": "web-program-pre1",
  "manifest": [
    {
      "path": "app/client.js",
      "where": "client",
      "type": "js",
      "cacheable": true,
      "url": "/client.js?hash=abc123",
      "size": 245678,
      "hash": "abc123..."
    }
  ]
}
```

**Server Program:**

```json theme={null}
{
  "load": [
    {
      "path": "server.js",
      "node_modules": "npm/node_modules",
      "assets": {
        "config.json": "assets/app/config.json"
      }
    }
  ]
}
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use imports/ for Everything">
    Put all application code in `imports/` and explicitly import it. This gives you:

    * Explicit dependency graph
    * Better code splitting
    * Easier testing
    * No reliance on load order
  </Accordion>

  <Accordion title="Minimal Entry Points">
    Keep `client/main.js` and `server/main.js` minimal - just imports:

    ```javascript client/main.js theme={null}
    import '/imports/startup/client';
    ```

    ```javascript server/main.js theme={null}
    import '/imports/startup/server';
    ```
  </Accordion>

  <Accordion title="Feature-Based Organization">
    Organize by feature, not by file type:

    ✅ Good:

    ```
    imports/features/tasks/
    imports/features/users/
    ```

    ❌ Avoid:

    ```
    imports/collections/
    imports/methods/
    imports/components/
    ```
  </Accordion>

  <Accordion title="Shared Code">
    Code outside `client/` and `server/` runs on both sides. Be careful with:

    * API keys (use server-only)
    * Node.js modules (check `Meteor.isServer`)
    * Browser APIs (check `Meteor.isClient`)
  </Accordion>
</AccordionGroup>

## Repository Structure

The Meteor source code itself follows this structure:

```bash theme={null}
meteor/
├── packages/           # 140+ core packages
├── tools/              # CLI & build system (Isobuild)
│   ├── cli/           # Command implementations
│   ├── isobuild/      # Build system
│   └── tests/         # Tool tests
├── npm-packages/       # Published @meteorjs/* packages
├── scripts/            # Build & release automation
├── docs/               # Documentation
└── v3-docs/            # Meteor 3.x docs
```

<Card title="Learn More" icon="book" href="/concepts/packages">
  Explore how Meteor's package system works and how packages are structured
</Card>
