# Understanding Encore

> How application code becomes running infrastructure

Encore is a platform for automating infrastructure from local development to cloud deployment. Instead of describing application architecture in separate infrastructure files, you declare services, APIs, and infrastructure resources in application code. Encore uses those declarations to run the application locally, validate it, and provision the infrastructure it needs in each environment.

The link between those capabilities is the **Encore Application Model**: a description of your application's services, APIs, resources, and the relationships between them. Encore derives the model from static analysis of your source code, without running it.

Encore runs a declared SQL database as a Postgres container locally and provisions it as RDS or Cloud SQL in the cloud. A declared Pub/Sub topic runs on a local broker, then on SNS and SQS or Google Cloud Pub/Sub, and so on.

## The core idea

Consider this declaration of a SQL database, one of Encore's infrastructure primitives for [TypeScript](/docs/ts) or [Go](/docs/go):

**Encore.ts:**

```ts
const db = new SQLDatabase("orders", { migrations: "./migrations" });
```

**Encore.go:**

```go
var db = sqldb.NewDatabase("orders", sqldb.DatabaseConfig{
    Migrations: "./migrations",
})
```

From this declaration, the parser records the database name and its migration directory. As it analyzes the rest of the application, it also records which services query the database.

Running `encore run` creates a Postgres database in a local container. When deploying with Encore's cloud platform, Encore provisions a managed Postgres instance and applies the same migrations. See [Development workflow](/docs/platform/workflow) for using the same declaration across local, preview, and production environments.

Encore rebuilds the model from source on every `encore run` and every build, keeping it synchronized with the code it describes. During the build, the parser validates the resource declarations it discovers and reports invalid declarations. The SDK, parser and compiler that produce the model are all [Open Source](https://github.com/encoredev/encore).

The development dashboard renders the model as an architecture diagram, where each box represents a service and shows its public, authenticated, and private endpoints and the databases it uses. Hovering over a service highlights its callers, API calls, and resource dependencies:

<video autoPlay playsInline loop muted className="w-full h-auto">
	<source src="/assets/docs/flow-diagram.mp4" type="video/mp4" />
</video>

## What the model enables

Because Encore understands the application rather than only its deployment configuration, the same model supports the whole development workflow:

- **Local infrastructure:** `encore run` starts local implementations of declared resources without a separate Docker Compose or emulator configuration.
- **Build-time validation:** the compiler reports invalid declarations and resource usage before deployment.
- **Development tooling:** the local dashboard provides API documentation, architecture diagrams, logs, traces, and a database explorer.
- **Type-safe communication:** Encore validates API schemas and generates clients for calling services and frontends.
- **Cloud provisioning:** deployments create the matching managed services in AWS or GCP and apply environment-specific capacity, networking, and backup settings.
- **Least-privilege access:** resource usage determines which services can call an API or access a database, bucket, or topic.

The open source SDKs, parser, compiler, CLI, and runtime provide the application model, local development, testing, and self-hosted builds. Encore's managed platform adds cloud provisioning, deployments, preview environments, and operational tooling in your own AWS or GCP account. You can use infrastructure outside the model alongside either approach.

## Inside the model

- Services, and the directory or package each one lives in
- API endpoints, with the full type schema of every request and response
- SQL databases and their migration directories
- Pub/Sub topics and subscriptions
- Cron jobs, object storage buckets, caches and secrets
- Middleware and API gateways

Running a build without supplying infrastructure configuration prints the part of the model that has to be satisfied:

```
$ encore build docker myapp:latest

Your infra configuration is incomplete

Missing Resource Configurations:
  Secrets      : SlackWebhookURL
  Databases    : monitor, site
  Subscriptions: uptime-transition/slack-notification, site.added/check-site
  Topics       : uptime-transition, site.added
```

## Deriving IAM and configuration

The model records how resources are used. Encore uses this information to derive IAM permissions and other configuration. For example, two services may use the same `uploads` bucket:

**Encore.ts:**

```ts
// in the ingest service
await uploads.upload("q3.csv", csvBytes);

// in the reports service
const csv = await uploads.download("q3.csv");
```

**Encore.go:**

```go
// in the ingest service
_, err := uploads.Upload(ctx, "q3.csv").Write(csvBytes)

// in the reports service
csv, err := uploads.Download(ctx, "q3.csv").All()
```

The parser records the download in `reports` and the upload in `ingest`. Encore grants `reports` read access to the bucket and `ingest` write access. Bucket usage distinguishes operations such as reading object contents, accessing metadata, and generating signed upload URLs. The model also records which services publish to each topic and call each endpoint.

**Encore.ts:**

The model drives provisioning, [request validation](/docs/ts/primitives/validation) against the declared schemas, [generated clients](/docs/ts/cli/client-generation), [API documentation](/docs/ts/develop/api-docs), and [distributed tracing](/docs/tracing) across service boundaries. These features use the application model as their shared source of service, resource, and schema information.

**Encore.go:**

The model drives provisioning, [request validation](/docs/go/develop/validation) against the declared schemas, [generated clients](/docs/go/cli/client-generation), [API documentation](/docs/go/develop/api-docs), and [distributed tracing](/docs/tracing) across service boundaries. These features use the application model as their shared source of service, resource, and schema information.

## Requirements on your code

Resource declarations are read from your source without running it, which constrains how you write them.

### Names must be string literals

A name assembled from a variable or a template fails the build:

**Encore.ts:**

```ts
const regions = ["eu", "us", "ap"];
export const orderTopics = regions.map(
  (r) => new Topic<string>(`orders-${r}`, { deliveryGuarantee: "at-least-once" }),
);
```

**Encore.go:**

```go
regions := []string{"eu", "us", "ap"}
for _, r := range regions {
    pubsub.NewTopic[string](fmt.Sprintf("orders-%s", r), pubsub.TopicConfig{
        DeliveryGuarantee: pubsub.AtLeastOnce,
    })
}
```

```
error: expected string literal
 --> orders/topics.ts:5:10
  |
5 |   (r) => new Topic<string>(`orders-${r}`, { deliveryGuarantee: "at-least-once" }),
  |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

### Declarations must be assigned at module scope

The parser collects top-level bindings. Constructor calls inside functions, conditionals, or loops are not included in the application model:

**Encore.ts:**

```ts
if (process.env.SHARD) {
  // Not part of the model, so never provisioned.
  new SQLDatabase("shard", { migrations: "./migrations" });
}
```

**Encore.go:**

```go
func init() {
    // Not part of the model, so never provisioned.
    sqldb.NewDatabase("shard", sqldb.DatabaseConfig{Migrations: "./migrations"})
}
```

API endpoint declarations must be exported. Service definitions must be the module's default export.

## Infrastructure outside the model

**Encore.ts:**

The application model supports a fixed set of resource types. Other infrastructure and third-party services are not included in the model. Provision resources such as search clusters or queues determined at runtime separately, connect to them as external dependencies, and store their connection details in a [secret](/docs/ts/primitives/secrets):

**Encore.go:**

The application model supports a fixed set of resource types. Other infrastructure and third-party services are not included in the model. Provision resources such as search clusters or queues determined at runtime separately, connect to them as external dependencies, and store their connection details in a [secret](/docs/go/primitives/secrets):

**Encore.ts:**

```ts
import { secret } from "encore.dev/config";

const searchEndpoint = secret("SearchEndpoint");

export const search = api(
  { expose: true, method: "GET", path: "/search" },
  async ({ q }: { q: string }): Promise<Results> => {
    const resp = await fetch(`${searchEndpoint()}/query?q=${q}`);
    return resp.json();
  },
);
```

**Encore.go:**

```go
var secrets struct {
    SearchEndpoint string
}

//encore:api public method=GET path=/search
func Search(ctx context.Context, q string) (*Results, error) {
    resp, err := http.Get(secrets.SearchEndpoint + "/query?q=" + q)
    // ...
}
```

Encore knows about the secret and the endpoint that uses it, so both appear in the model, while the cluster behind the endpoint does not.

The [Terraform Provider](/docs/platform/integrations/terraform) also exposes data sources for infrastructure provisioned by Encore, allowing existing Terraform configurations to reference an Encore database or topic by name.

## Frequently asked questions

### Can I see the model?

Yes. The [local development dashboard](/docs/dev-dash) renders it as a service catalog and an architecture diagram, so you can inspect the services, endpoints and resources the parser found.

### Does my source code get sent anywhere?

Static analysis itself does not send your source code anywhere. The open source parser runs in the environment where the build is performed, including locally during `encore run`.

### What if someone changes a resource in the cloud console?

The application model and the state of provisioned infrastructure are managed separately. The model is derived from the application code. If a resource is modified outside Encore, the next deploy detects the change and updates Encore's record instead of overwriting it. See [managing infrastructure](/docs/platform/infrastructure/managing-infrastructure).

### Does static analysis constrain the rest of my code?

No. The requirements above apply to resource declarations. Static analysis does not otherwise restrict the libraries, patterns, or abstractions used in your application logic.

### Does static analysis slow down my builds?

No. The parser runs during the build, before infrastructure provisioning, and adds little next to compilation and building the container image.

### Is the model specific to TypeScript?

No. Encore builds the same application model for TypeScript and Go applications, using a parser designed for each language.
