# Compilation pipeline

When you run a build, Comind.work transforms your TypeScript source into a compiled schema that the platform can execute. The pipeline has five stages: load, parse, bundle, compile, and deploy.

## Pipeline overview[​](#pipeline-overview "Direct link to Pipeline overview")

```
1. LOAD SOURCE
   ├── Read app's TS/TSX files from disk
   ├── Recursively load dependencies (base, plugins, parent)
   └── Return virtual filesystem map: { path -> source }

2. BUILD SCHEMA OBJECT
   ├── Parse fields/index.ts -> field definitions
   ├── Parse actions/index.ts -> action definitions
   ├── Parse views/layouts/*.tsx -> layout descriptors
   ├── Parse settings/index.ts -> app settings
   ├── Compose from all dependency layers (base -> plugins -> app)
   ├── Apply app-mutator.ts transformations
   └── Return: complete schema object

3. BUNDLE CODE
   For each entry point, bundle with a virtual filesystem:
   ├── fields/calc-fields/index.ts -> bundled calc field code
   ├── actions/logic/index.ts -> bundled action logic
   ├── views/layouts/*.tsx -> bundled JSX-to-XML layouts
   └── views/logic/index.ts -> bundled UI hooks

4. COMPILE TO JS
   ├── Serialize options, fields, actions, layouts, settings
   ├── Create getter functions for each component
   └── Output: app registration with getFields(), getActions(), etc.

5. DEPLOY
   ├── Register the app in the target workspace
   ├── Store the compiled schema
   └── Frontend loads schema on next page load
```

## Stage details[​](#stage-details "Direct link to Stage details")

### 1. Load source[​](#1-load-source "Direct link to 1. Load source")

The pipeline begins by reading the app's TypeScript and TSX files from disk. It then walks the dependency chain - base app, [plugins](/developer-guide/building-blocks/plugins-and-inheritfrom.md), and parent apps - loading each layer recursively. The result is a virtual filesystem map that pairs every file path with its source content. See [Package structure](/developer-guide/app-architecture/package-structure.md) for how files are organized on disk.

### 2. Build schema object[​](#2-build-schema-object "Direct link to 2. Build schema object")

The loader output feeds into the schema builder, which parses each well-known entry point into a typed structure:

* `fields/index.ts` produces the field definitions
* `actions/index.ts` produces the action definitions
* `views/layouts/*.tsx` produces the layout descriptors
* `settings/index.ts` produces app-level settings

The builder composes these structures across all dependency layers, applying `app-mutator.ts` transformations last. The final `AppSchemaObject` contains everything the bundler needs.

### 3. Bundle code[​](#3-bundle-code "Direct link to 3. Bundle code")

The bundler processes each entry point using a virtual filesystem, so no temporary files touch disk during compilation. It uses fast TypeScript transpilation to produce optimized bundles.

Several built-in transforms handle platform-specific concerns:

* Server-only imports are stripped from client bundles
* Code is validated to stay within allowed module boundaries
* Heavy libraries are aliased for smaller output

### 4. Compile to JavaScript[​](#4-compile-to-javascript "Direct link to 4. Compile to JavaScript")

The compiler serializes the schema object into executable JavaScript. It creates getter functions for each component - fields, actions, layouts, settings - and wraps them in a single app registration call.

### 5. Deploy[​](#5-deploy "Direct link to 5. Deploy")

The compiled code is sent to the platform. It registers the app in the target workspace, stores the schema, and the frontend picks it up on the next page load. You can trigger a deploy from the [CLI](/developer-guide/reference/cli-reference.md) or through the builder server.

## Local vs remote bundling[​](#local-vs-remote-bundling "Direct link to Local vs remote bundling")

The bundler can run in two modes:

* **Locally** - the bundler runs inside the CLI process on your machine
* **Remotely** - the CLI sends a request to the builder server

The builder server exposes several endpoints beyond bundling:

| Endpoint     | Purpose                  |
| ------------ | ------------------------ |
| Bundler      | Code bundling            |
| App builder  | Full schema build        |
| Type checker | TypeScript type checking |
| Test runner  | Jest test execution      |
| Linter       | ESLint linting           |
| Formatter    | Prettier formatting      |

## Dual execution[​](#dual-execution "Direct link to Dual execution")

The compiled output runs in two places:

* **Browser** - JavaScript executes natively for form rendering, field visibility, validation, and calc fields
* **Server** - the platform's server runtime runs action logic, data manipulation, and server-side operations

This dual-execution model is why apps are written in TypeScript. The same code must work in both environments, so the pipeline produces plain JavaScript that both runtimes can consume. Keep this constraint in mind when writing action logic - avoid browser-only or Node-only APIs. See [App lifecycle](/developer-guide/app-architecture/app-lifecycle.md) for how the compiled schema behaves at runtime.

## Related[​](#related "Direct link to Related")

* [Standard apps catalog](/developer-guide/app-architecture/standard-apps-catalog.md) - the full list of platform apps that go through this pipeline
* [Testing apps](/developer-guide/how-to/advanced/testing-apps.md) - run Jest tests to validate calc fields and action logic before compilation
