~ / freestyle-team ❯ Introducing Rigkit
Define your development environment as code.
Cloud agents are having a moment. Codex, Claude Code, Cursor's background agents, T3Code. Everyone wants their agents to run in the cloud.
But Cloud agents are hard. My Macbook has all my apps, my clis authed into my accounts, my residential IP address. My Cloud agents don't.
So we made the development environment a configuration. Write it once, and spin up already-authenticated, already-configured development environment in milliseconds.
Terraform for development environments?
We realized Terraform solved this exact problem for production environments. And so rigkit naturally inherited some of their ideas:
rig plan reads your config and tells you what would need to run:
rig apply runs steps to create a development environment. If a step needs a human, like logging into GitHub, it opens a terminal and waits:
rig create creates a fresh, authenticated development environment from what was applied.
rig run <name> <operation> runs anything your config defines against a workspace. Here open-vscode opens it in VS Code:
Why not Docker? Why not Terraform?
It turns out development environments are messier than production environments.
- Some CLIs want OAuth.
gh,gcloud, andvercelexpect a human in a browser. - Some environments just want an environment variable. A coding review bot can't use OAuth, it might need to use environment variables injected in CI.
- Everyone's setup is a little different. One coworker wants neovim and their dotfiles. Another wants nothing but the repo.
So instead of JSON, or a DSL like Terraform's, we turned to Typescript.
Development environments as code
All of rigkit is defined in a Typescript file. Running rig apply, or rig create simply executes Typescript
Because it's Typescript, weird parts of your development environment become Typescript. Need to OAuth into gh? Run some code that opens a terminal in the middle of the task, let a human log in. Have an API key instead? Read it from process.env. A coworker wants neovim and their dotfiles? They add a conditional task. Code review needs a headless box with no editor at all? Use environment overrides.
Here is an example Next.js config:
import { workflow } from "@rigkit/sdk";
import { freestyle } from "@rigkit/provider-freestyle";
const app = workflow("playground");
// A Freestyle VM reaches nothing it has not been allowed to.
const firewall = {
rules: [{ action: "allow", source: {}, destination: { public: true } }],
};
export const playground = app
.sequence("playground")
.addProvider("freestyle", freestyle.provider())
.task("clone-and-install", async ({ providers }) => {
const { vm, vmId } = await providers.freestyle.client.vms.create({ firewall });
const root = vm.linuxUser("root");
await root.exec("git clone https://github.com/freestyle-sh/freestyle-next /workspace/app");
await root.exec("cd /workspace/app && bun install");
const snapshot = await vm.snapshot();
await providers.freestyle.client.vms.delete(vmId);
return { ctx: { snapshotId: snapshot.snapshotId } };
})
.workspace({
create: async ({ workflow, providers }) => {
const { vmId } = await providers.freestyle.client.vms.create({
snapshotId: workflow.ctx.snapshotId,
firewall,
});
return { vmId, repoPath: "/workspace/app" };
},
remove: async ({ providers, workspace }) => {
await providers.freestyle.client.vms.delete(workspace.ctx.vmId);
},
})
.workspaceOperation("open-vscode", {
title: "Open VS Code",
run: async ({ providers, workspace, local }) => {
const url = await providers.freestyle.vscode.createUrl({
vmId: workspace.ctx.vmId,
cwd: workspace.ctx.repoPath,
});
await local.open(url);
},
});Want to give it a shot?
Paste this into your agent and it will set up rigkit with Freestyle VMs in your repo: