<!-- Source: https://docs.squirro.com/en/latest/technical/neo/dev-guide/project-structure.html -->
# Project Structure

> **Warning**
>
> Project Neo is currently in [Technical Preview](../../../a-z/squirro-glossary.md#term-Technical-Preview). Features described in this section may change before general availability.

## Directory Layout

After running `neo-ui create bundle my-dashboards`, the bundle directory has the following layout:

```text
my-dashboards/
├── package.json              # npm scripts and dependency declarations
├── rsbuild.config.ts         # Build configuration (do not change)
├── tsconfig.json             # TypeScript config (extends core base config)
├── biome.json                # Linting and formatting config (extends core config)
├── components.json           # shadcn/ui component config (for adding components)
├── index.html                # HTML shell entry point
├── .env                      # Credentials and port settings (never commit)
├── .env.example              # Committable template of the .env keys
├── CLAUDE.md                 # AI-assisted development guidelines
├── .gitignore                # Pre-configured to exclude .env and node_modules
├── .claude/
│   └── skills/               # Squirro skills for Claude Code (API, items, components, chat, dashboard design, deploy, translations)
└── src/
    ├── manifest.ts           # Bundle manifest, your main configuration file
    ├── theme.ts              # Brand theme: colors, logo, favicon (edit to brand)
    ├── bootstrap.ts          # Module Federation bootstrap (do not edit)
    ├── main.tsx              # Standalone dev preview only (not loaded in production)
    ├── dev-tools.ts          # Translation key dev overlay (do not edit)
    ├── index.css             # Global styles for your bundle
    ├── env.d.ts              # Ambient TypeScript declarations (do not edit)
    ├── utils.ts              # cn() utility for combining class names
    └── dashboards/
        └── Analytics.tsx     # Your dashboard components live here
```

## What to Edit

| File | Editable | Notes |
| --- | --- | --- |
| `src/dashboards/*.tsx` | **Yes** | All dashboard UI lives here. |
| `src/theme.ts` | **Yes** | Brand colors, logo, and favicon. Edit to match the customer brand. |
| `src/manifest.ts` | **Occasionally** | Managed by the CLI. Edit manually only to reorder dashboards or change an icon. |
| `src/index.css` | **Yes** | Global bundle styles. |
| `.env` | **Yes** | Update credentials or ports. Use `neo-ui config` for interactive editing. |
| `package.json` | **Occasionally** | Only when adding approved third-party libraries. |
| `rsbuild.config.ts` | **Rarely** | Advanced Module Federation customization only. |
| `CLAUDE.md` | **Occasionally** | AI coding guidelines. Adjust if using Claude Code. |
| `bootstrap.ts` | **No** | Module Federation async bootstrap entry. Do not modify. |
| `main.tsx` | **No** | Standalone dev preview entry. Not loaded in production. The CLI updates it automatically when you add or remove dashboards. |
| `dev-tools.ts` | **No** | Translation key development overlay. Do not modify. |

## Key Files

### src/manifest.ts

The manifest is the contract between your bundle and the host application. It declares every dashboard your bundle provides. The CLI manages it when you run `neo-ui create dashboard` or `neo-ui remove dashboard`, but you can also edit it manually.

```typescript
import { defineBundleManifest } from '@squirro/neo-core';
import theme from './theme';
// Import the bundle styles here, not only in main.tsx: the host loads the
// bundle through this manifest and never executes main.tsx.
import './index.css';

declare const NEO_CORE_VERSION: string;

if (import.meta.env.DEV) {
  void import('./dev-tools');
}

export default defineBundleManifest({
  name: 'my-dashboards',                   // unique identifier for your bundle
  platformVersion: NEO_CORE_VERSION,    // injected at build time by the CLI
  dashboards: [
    {
      id: 'analytics',
      title: 'Analytics',
      icon: 'bar-chart-3',
      route: 'analytics',
      component: () => import('./dashboards/Analytics'),
    },
  ],
  theme,                                    // brand defaults from src/theme.ts
  isBrandingSource: false,                   // set true on exactly one bundle per tenant
});
```

For the full manifest format reference, see the [The Bundle Manifest](manifest.md#neo-extensions-manifest) page.

### src/main.tsx

`main.tsx` is the entry point for the standalone development preview. When `neo-ui dev` starts the bundle server, this file renders a minimal React application into `index.html` so you can browse your dashboards in a browser without a live Squirro instance.

> **Important**
>
> `main.tsx` does not run in production. When the host application loads your bundle, it imports only `src/manifest.ts` via Module Federation. Any initialization code placed in `main.tsx` is silently absent at runtime.
>
>
>
> Place startup logic such as provider setup or global state initialization inside your dashboard components, not in `main.tsx`.

The CLI manages this file. It adds and removes route entries automatically when you run `neo-ui create dashboard` or `neo-ui remove dashboard`. You do not need to edit it manually.

### src/dashboards/

This directory contains your React components. Each file corresponds to one dashboard. The CLI creates a starter file when you run `neo-ui create dashboard`.

Every dashboard component receives a `projectId` prop, injected automatically by the host:

```typescript
export default function Analytics({ projectId }: { projectId: string }) {
  // use projectId to fetch data for the active project
}
```

### src/index.css

Global styles loaded for the entire bundle. The host theme tokens for colors, typography, and spacing are already available. Add bundle-specific styles here:

```css
@import "tailwindcss";
@import '@squirro/neo-core/styles/theme.css';
/* @source is a Tailwind filesystem glob, so it needs a relative path */
@source "../node_modules/@squirro/neo-core/dist";

/* your custom styles below */
```

The `@import "tailwindcss";` line is what makes Tailwind utility classes work out of the box. The theme import provides the host design tokens, and `@source` lets Tailwind scan the host components so their classes are not purged.

### .env

Contains credentials and port settings.

> **Warning**
>
> Never commit this file. It is already included in `.gitignore`.

```bash
# Squirro API configuration
SQUIRRO_API_URL=https://your-instance.example.com
SQUIRRO_TOKEN=your-refresh-token

# Optional: override defaults
# BUNDLE_PORT=3001
# DEV_PROXY_PORT=5555
```

Restrict the file permissions so that only your user account can read it:

```bash
chmod 600 .env
```

To update these values interactively, run `neo-ui config`.

### rsbuild.config.ts

The entire build configuration is a single line:

```typescript
import { createBundleConfig } from '@squirro/neo-core/config';

export default createBundleConfig({ name: 'my-dashboards' });
```

`createBundleConfig` sets up Module Federation, Tailwind CSS, TypeScript, CORS for the development server, and all other build settings. You rarely need to modify this file.

## Updating Dependencies

The `@squirro/neo-core` and `@squirro/neo-ui` packages are installed from the public npm registry during bundle creation, because `neo-ui create bundle` runs `npm install` for you. They are pinned in `package.json` to the version that was current when you created the bundle.

To update both `@squirro` package versions and reinstall, run a single command:

```bash
neo-ui upgrade
```

The same command migrates a bundle that still depends on the pre-rename `@squirro/nextgen-core` package. For more information, see the [Migrating from nextgen to neo-ui](migrating-from-nextgen.md#neo-extensions-migrating) page.

After updating, restart `neo-ui dev` or run `neo-ui build` for the changes to take effect.
