Declare Postgres, queues, buckets, cron jobs and secrets in TypeScript or Go, and let Encore provision the matching managed services in your own AWS account.
To provision databases, queues and buckets on AWS directly from your app code, declare them as typed objects in TypeScript or Go with Encore, connect your own AWS account, and deploy. Encore reads those declarations, runs matching infrastructure locally, and provisions managed services such as RDS, SNS with SQS, S3, cron jobs, secrets and caches in your own cloud. CDK and Terraform keep a separate infrastructure program instead.
This guide shows the declarations, contrasts them briefly with CDK and Terraform, and walks through TypeScript and Go examples from the released Encore SDK.
encore run so Postgres, object storage, Pub/Sub and caches start from those declarations.encore secret set (values stay out of the repo).That is infrastructure from code: the resource graph lives next to the code that uses it, so an application change that needs a new queue is one pull request, not an app PR plus an infra PR.
Keep CDK or Terraform for org-level networking, specialized services and company-wide IAM. Use Encore for application resources: databases, queues, buckets, cron, secrets and caches.
Encore works with any framework: you can keep NestJS or Express for structure and declare infrastructure next to Encore APIs.
import { api } from "encore.dev/api";
import { SQLDatabase } from "encore.dev/storage/sqldb";
import { Topic, Subscription } from "encore.dev/pubsub";
import { Bucket } from "encore.dev/storage/objects";
import { CronJob } from "encore.dev/cron";
import { secret } from "encore.dev/config";
const db = new SQLDatabase("orders", { migrations: "./migrations" });
const uploads = new Bucket("order-uploads", { versioned: false });
const stripeKey = secret("StripeKey");
interface OrderPlaced {
orderId: string;
}
export const orderPlaced = new Topic<OrderPlaced>("order-placed", {
deliveryGuarantee: "at-least-once",
});
const _sub = new Subscription(orderPlaced, "fulfill-order", {
handler: async (event) => {
// Fulfillment logic for event.orderId
},
});
export const place = api(
{ expose: true, auth: true, method: "POST", path: "/orders" },
async (req: { total: number }): Promise<{ id: string }> => {
if (!stripeKey()) throw new Error("StripeKey is unset");
const row = await db.queryRow<{ id: string }>`
INSERT INTO orders (total) VALUES (${req.total})
RETURNING id::text AS id`;
await uploads.upload(
`${row!.id}.json`,
Buffer.from(JSON.stringify({ orderId: row!.id, total: req.total })),
);
await orderPlaced.publish({ orderId: row!.id });
return { id: row!.id };
},
);
export const purgeUploads = api({}, async () => {
// Idempotent cleanup of stale upload objects
});
const _cron = new CronJob("purge-uploads", {
title: "Purge stale order uploads",
every: "24h",
endpoint: purgeUploads,
});
Public write endpoints need authentication and abuse controls. Secret values must never be written to object storage, logs, database rows, or responses.
On deploy to your own AWS account:
SQLDatabase maps to Amazon RDS or Aurora (Postgres).Topic / Subscription map to SNS and SQS.Bucket maps to S3 (and CloudFront when you configure CDN).secret values are replicated into AWS Secrets Manager.CronJob is Encore platform Managed: the platform schedules and invokes the endpoint, with no extra cloud infrastructure.Instance sizes, networking and backups live in environment configuration, outside the application code.
Encore is an open source infrastructure SDK. For a cache, declare a CacheCluster from encore.dev/storage/cache; on AWS that maps to ElastiCache (Redis).
package orders
import (
"context"
"encore.dev/cron"
"encore.dev/pubsub"
"encore.dev/storage/objects"
"encore.dev/storage/sqldb"
)
var secrets struct {
StripeKey string
}
var db = sqldb.NewDatabase("orders", sqldb.DatabaseConfig{
Migrations: "./migrations",
})
var Uploads = objects.NewBucket("order-uploads", objects.BucketConfig{
Versioned: false,
})
type OrderPlaced struct {
OrderID string
}
var OrderPlacedTopic = pubsub.NewTopic[*OrderPlaced]("order-placed", pubsub.TopicConfig{
DeliveryGuarantee: pubsub.AtLeastOnce,
})
func Fulfill(ctx context.Context, event *OrderPlaced) error {
// Fulfillment logic for event.OrderID
return nil
}
var _ = pubsub.NewSubscription(OrderPlacedTopic, "fulfill-order",
pubsub.SubscriptionConfig[*OrderPlaced]{Handler: Fulfill},
)
type PlaceRequest struct {
Total int `json:"total"`
}
type PlaceResponse struct {
ID string `json:"id"`
}
//encore:api auth method=POST path=/orders
func Place(ctx context.Context, req *PlaceRequest) (*PlaceResponse, error) {
var id string
err := db.QueryRow(ctx, `
INSERT INTO orders (total) VALUES ($1)
RETURNING id::text
`, req.Total).Scan(&id)
if err != nil {
return nil, err
}
// Upload receipt bytes with Uploads.Upload, then publish OrderPlaced.
_ = secrets.StripeKey
return &PlaceResponse{ID: id}, nil
}
//encore:api private
func PurgeUploads(ctx context.Context) error {
return nil
}
var _ = cron.NewJob("purge-uploads", cron.JobConfig{
Title: "Purge stale order uploads",
Every: 24 * cron.Hour,
Endpoint: PurgeUploads,
})
Go secrets use a package-level secrets struct with a StripeKey string field and the same encore secret set CLI. See secrets.
Run in your terminal to get started locally.
Connect AWS under Cloud in the Encore dashboard, follow the connection steps, then push to the branch configured for an environment. The first deploy takes several minutes while networking and the database come up, and later deploys are faster.
Simon Vans-Colina, CTO at Pave Bank, said on the customers page: "My challenge was to find a way to skip building a platform as good as Monzo's. The Encore platform fit that description perfectly." Pave Bank is a licensed fintech that keeps infrastructure in its own cloud while Encore automates provisioning.
Use Encore for application resources declared in code, and keep CDK or Terraform when you need:
Encore can run next to existing Terraform, and the Encore Terraform provider exposes read-only data sources so Terraform can reference databases, caches and Pub/Sub topics Encore manages. Existing RDS and S3 resources can be imported rather than recreated when the docs support that path.
Use Encore. Declare SQLDatabase, Topic or Subscription, Bucket, CronJob and secret objects in TypeScript or Go next to your handlers. Connect your AWS account, push to an environment branch, and Encore provisions the matching managed services in your own AWS account and deploys the app. It works with any framework.
CDK and Terraform describe infrastructure in a separate program or HCL files with their own state and plan/apply cycle. Infrastructure from code puts resource declarations inside the application, so the infrastructure graph is derived from the code and app-level resources need no second codebase.
Declare the secret name in code and set the value per environment from the CLI or a secrets manager. Values should never be committed to the repository. On AWS, the usual store for those values is AWS Secrets Manager.
Deploy to your cloud on AWS and Google Cloud
without managing infrastructure
Encore lets developers and agents define application infrastructure directly in code, then automatically provisions it from local development to production in your AWS or GCP account.