Deploy Workers Programmatically


Some apps give their users a backend, like an app builder where each project gets its own API. For that, your app has to deploy the backend from code, at the moment the user needs it.

With the Workers API, your app creates a serverless worker, updates its code and removes it, the same way it writes files. Each worker answers at its own URL, and there is no server for you to run.

Create a Worker

A worker is deployed from a JavaScript file in your Puter account. Write the code with puter.fs.write(), then pass the file to puter.workers.create() along with a name:

await puter.fs.write('notes-api.js', `
    router.get('/me', async ({ user }) => {
        const { username } = await user.puter.getUser();
        return { username };
    });
`);

const deployment = await puter.workers.create('notes-api', 'notes-api.js');

deployment.url;    // 'https://notes-api.puter.work'

Give it 5 to 30 seconds before the first request, while the worker spreads to every edge server. Then call it with puter.workers.exec(), which sends the signed-in user along so the route can use user.puter:

const res = await puter.workers.exec(`${deployment.url}/me`);
await res.json();    // { username: 'grace' }

Build an API with a worker covers what to put in the routes.

Worker names are global, like subdomains, and are stored in lowercase. A name can use letters, numbers, hyphens and underscores. When another account already has the name, create() rejects, so pick another one or use puter.randName(). The account deploying the worker needs a verified email address.

Update Its Code

A worker keeps its name and URL for as long as it exists. To change what it runs, overwrite its source file. puter.workers.get() tells you where that file is:

const info = await puter.workers.get('notes-api');

await puter.fs.write(info.file_path, updatedCode);

Writing the file redeploys the worker at the same URL, so anything already calling it keeps working.

Find Your Workers

To show the workers in your account, call puter.workers.list():

const workers = await puter.workers.list();

for (const worker of workers) {
    console.log(worker.name, worker.url);
}

To look up one worker by name, use puter.workers.get(). It resolves to undefined when there is no worker with that name, which makes it a quick existence check before a deploy:

const existing = await puter.workers.get('notes-api');

if (!existing) {
    await puter.workers.create('notes-api', 'notes-api.js');
}

Keep Workers Apart

Inside a worker, me.puter reaches the key-value store and files of the app the worker runs as. When your app creates workers, they run as your app by default, so they all share that data with each other and with your app.

To give each worker its own data, pass sandbox: true:

await puter.workers.create('project-alpha-api', 'alpha.js', { sandbox: true });
await puter.workers.create('project-beta-api', 'beta.js', { sandbox: true });

Each worker now runs as its own app, so a key one of them writes is not visible to the other. Decide this before the worker stores anything, because changing it later does not move data that was already written.

Delete a Worker

To take a worker offline, call puter.workers.delete() with its name:

await puter.workers.delete('notes-api');

Its URL stops answering, and the name is free to use again. The source file stays in your account.

Deleting a worker's source file with puter.fs.delete() also deletes the worker, so keep the file for as long as the worker should stay online.

← All recipes