Quickstart
This quickstart deploys a first stack, the code and cloud resources you describe in alien.ts, to an environment you don't host. You can have a coding agent add Alien to your own repository, or build a small example by hand.
With your coding agent
Paste this into your coding agent, from your repository:
The agent installs the Alien skills, reads your code, Dockerfiles, and Helm charts, and proposes what runs in customer environments. It stops for your choice before editing, and asks before it publishes a release or creates a customer deployment. See Build with an AI agent.
By hand
This path builds a worker, a serverless function, that reads and writes files in the customer's own storage. Your backend calls it with commands: named functions in your code that run inside the customer's environment.
Architecture diagram. Customer's cloud (worker, files) connects outbound to the Your cloud (Your backend, alien CLI), via commands, outbound only.
You run it locally first, with no cloud account, then deploy the same code to an AWS, Google Cloud, or Azure account you control.
Prerequisites
- macOS, Linux, or Windows
- Node.js 20 or later
- Bun (Alien builds TypeScript with it)
- Docker, running (
alien devuses it to run your code locally)
Install the CLI
curl -fsSL https://alien.dev/install | shCheck the install with alien --version.
The install script puts alien in /usr/local/bin if that directory is writable, otherwise in ~/.local/bin, and adds it to your shell profile. If your shell can't find alien, open a new terminal or run the export PATH=... line the script prints.
Create the project
alien init remote-worker-ts my-worker
cd my-workeralien.ts describes what each customer gets:
import * as alien from "@alienplatform/core"
// Private file storage in each customer's environment.
// S3 on AWS, Cloud Storage on Google Cloud, Blob Storage on Azure.
const files = new alien.Storage("files").build()
// Your code. Lambda on AWS, Cloud Run on Google Cloud,
// Container Apps on Azure.
const worker = new alien.Worker("worker")
.code({ type: "source", src: "./", toolchain: { type: "typescript" } })
.commandsEnabled(true)
.link(files)
.permissions("execution")
.build()
export default new alien.Stack("remote-worker")
.platforms(["aws", "gcp", "azure"])
.add(files, "frozen")
.add(worker, "live")
.permissions({
profiles: {
execution: { "*": ["storage/data-read", "storage/data-write"] },
},
})
.build().link(files)gives the worker access to the bucket at runtime. Credentials come from the environment; there is no connection string.filesis frozen: it's created once, at initial setup (the one-time step the customer's admin runs in their account), and Alien can't change or delete it afterwards.workeris live: Alien updates it on every release. See Frozen and live resources..commandsEnabled(true)lets your backend send the worker commands.
src/index.ts is the code that runs there. It registers commands with command() and reads the customer's files with storage():
import { command, storage } from "@alienplatform/sdk"
import { z } from "zod"
const tools = {
"read-file": async ({ path }: { path: string }) => {
const object = await storage("files").get(path)
return { content: new TextDecoder().decode(object.data) }
},
"write-file": async ({ path, content }: { path: string; content: string }) => {
await storage("files").put(path, new TextEncoder().encode(content))
return { written: true, path }
},
}
command(
"execute-tool",
z.object({ tool: z.enum(["read-file", "write-file"]), params: z.any() }),
async ({ tool, params }) => tools[tool](params),
)The template's version also has list-tools and where-am-i commands.
Run it locally
alien devalien dev starts a local manager (the Alien server that stores releases and rolls them out), builds and releases the worker, and deploys it. Storage is a local directory. Keep it running.
Building... done
Starting... done
default: Running
execution-sa: running (private)
files: local filesystem
secrets: running (private)
worker: running (private)A deployment is one running copy of your stack. default stands in for your first customer.
Deployments belong to a deployment group, usually one per customer. The local group is local-dev, so the full name is local-dev/default.
Call the worker
In a second terminal, from my-worker, write a file into the customer's storage and read it back:
alien dev commands invoke \
--deployment local-dev/default \
--command execute-tool \
--params '{"tool": "write-file", "params": {"path": "hello.txt", "content": "Hello!"}}'{ "path": "hello.txt", "written": true }alien dev commands invoke \
--deployment local-dev/default \
--command execute-tool \
--params '{"tool": "read-file", "params": {"path": "hello.txt"}}'{ "content": "Hello!" }Add a second customer
alien dev deploy --name customer-2 --platform localcustomer-2 gets its own worker and its own storage. Reading hello.txt from local-dev/customer-2 fails with Storage object not found: the file only exists in default's storage. In production, the two would be separate cloud accounts.
Change the code
Add a command to the end of src/index.ts:
command("hello", async () => ({ message: "Hello from the new release" }))Stop alien dev with Ctrl+C and start it again. It rebuilds the worker, creates a new local release, and updates both deployments:
alien dev commands invoke --deployment local-dev/customer-2 --command hello{ "message": "Hello from the new release" }Deploy to a cloud account
Run the same worker in a real cloud account. You play two roles: the developer who releases, and the customer's admin who runs initial setup once.
Sign in and link the project
alien login
alien linkalien login opens your browser to sign in to alien.dev. A new account has no workspace yet: create one with alien workspaces create <name>. The name is permanent and appears in dashboard URLs (4 to 100 lowercase letters, numbers, and hyphens).
alien link creates a project for this directory, or links it to an existing one, and saves the link in .alien/project.json.
Release
alien releaseThis builds the worker for each platform the stack declares and uploads the images. It also moves the production channel, the pointer deployments follow by default, to the new release. Nothing runs in a customer environment yet.
Onboard a customer
alien onboard customer-1The output is a setup link, a URL the customer's admin opens to run initial setup:
Share this link with the customer's admin:
https://alien.dev/deploy/#<token>The link opens the deployment portal, a setup page branded with your project's name. Onboard a customer in the dashboard creates the same link. Your backend can create links through the API, for example behind a Deploy button.
Run initial setup as the customer's admin
Open the link, pick a cloud, and pick a setup method: CloudFormation, Terraform, Helm, Google login, or a CLI named after your project.
For this guide, choose CLI. Follow the portal's commands in a terminal that has credentials for your cloud account (for example AWS_PROFILE):
- An install command for the setup CLI. Its default name is the project name plus
-ctl(my-worker-ctl), or plusctlwhen the name has no hyphen. You can rename it under project Settings → Artifacts. - A
deployment.tomlwith the deployment's name, platform, and settings. Save it in the current directory. - The deploy command. It passes the setup token in an environment variable named after the CLI, so the token stays out of the command line:
export MY_WORKER_CTL_DEPLOYMENT_TOKEN='<token-from-the-portal>'
my-worker-ctl deploy --config deployment.tomlInitial setup uses your credentials once, and doesn't store them. It creates the bucket and a management identity: a scoped cloud role Alien uses to manage the deployment afterwards. Alien then creates the worker with that identity.
Watch the deployment come up in the dashboard under Deployments, or from the CLI:
alien deployments lsCall the worker in the cloud
A deployment is addressed as <group>/<name>. alien onboard customer-1 created a deployment group and a deployment both named customer-1:
alien commands invoke \
--deployment customer-1/customer-1 \
--command execute-tool \
--params '{"tool": "write-file", "params": {"path": "hello.txt", "content": "Hello from the cloud"}}'The same handler now runs in Lambda, Cloud Run, or Container Apps, and writes to a bucket in that account.
Ship an update
Change the code and release again:
alien release
alien deployments wait customer-1/customer-1 --for readyThis is ongoing management: Alien updates the deployment, and the admin doesn't run anything. The release reaches every deployment on the production channel.
In the dashboard, the release page under Releases shows each deployment's rollout state.
Clean up
Remove the deployment with the same method the admin used for initial setup:
| Setup method | How to remove it |
|---|---|
| CLI | Set the token variable again and run my-worker-ctl destroy --name customer-1. |
| CloudFormation | Delete the stack. The portal shows the stack's name and region, with a link to it in the AWS console. |
| Terraform | In the workspace that applied the module, set TF_VAR_token to the setup token and, on AWS, TF_VAR_management_external_id to the ExternalId used at initial setup. Then run terraform destroy. If the stack defines a Key, first run the module's detach-retained-keys.sh, as its README describes. It removes the keys from Terraform state and leaves them in the account. |
| Helm | Run helm list --all-namespaces to find the release and namespace, then helm uninstall <release> --namespace <namespace>. |
Removal keeps storage buckets so no data is lost. Delete them yourself when you're done.
On Azure, the Terraform module requires the azurerm provider at version 4.75 or later, below 5.0. In a workspace locked to an older version, run terraform init -upgrade first.
The Azure module won't delete a resource group that still contains resources, such as a retained Key Vault. terraform destroy stops with an error and the group stays.
Next
- How Alien works: initial setup, ongoing management, and how releases reach each environment.
- Architecture design: decide which part of your product runs in each customer's environment.
- Stacks: resources, commands, and releases in depth.
Introduction
Alien provides infrastructure for deploying and operating software in remote environments at scale, close to sensitive data, private networks, local resources, and latency-critical workloads.
How Alien works
The one-time initial setup the customer's admin runs, the ongoing management Alien does on every release, and what Alien can and can't do in a customer's account.