# Workers

import {
	LinkCard,
	PackageManagers,
	Render,
	Tabs,
	TabItem,
	TypeScriptExample,
	WranglerConfig,
	Steps,
} from "~/components";

Create an Artifacts repo from a Worker and use a standard Git client to push and pull content.

By the end of this guide, you will create a Worker, bind it to Artifacts, create a repo through the Workers binding, push a commit, and clone the same repo back with a standard Git client.

Start by reading [Namespaces](/artifacts/concepts/namespaces/), then choose the namespace name you will use. This guide uses `default` in the examples.

## Set up with your coding agent

<Render file="agent-setup" product="artifacts" />

To set up Artifacts manually, follow the steps below.

## Prerequisites

<Render file="prereqs" product="workers" />

You also need:

- Wrangler installed. If you use local Wrangler commands in this guide, authenticate Wrangler first. For local OAuth authentication or CI setup, refer to [`wrangler login`](/workers/wrangler/commands/general/#login) and [Running Wrangler in CI/CD](/workers/ci-cd/).
- Access to Artifacts on the [Workers Paid plan](/artifacts/platform/pricing/).
- A namespace name, for example `default`.
- A local `git` client.
- `jq`, if you want to extract response fields automatically.

## 1. Create a Worker project

<Steps>

1. Create a new Worker project with C3:

   <PackageManagers
   	type="create"
   	pkg="cloudflare@latest"
   	args={"artifacts-worker"}
   />

   <Render
   	file="c3-post-run-steps-hello-world"
   	product="workers"
   	params={{
   		type: "Worker only",
   		lang: "TypeScript",
   	}}
   />

2. Move into the project directory:

   ```sh
   cd artifacts-worker
   ```

</Steps>

## 2. Add the Artifacts binding

Open your Wrangler config file and add the Artifacts binding:

<WranglerConfig>

```toml title="wrangler.toml"
name = "artifacts-worker"
main = "src/index.ts"
upload_source_maps = true
compatibility_date = "$today"

[[artifacts]]
binding = "ARTIFACTS"
namespace = "default"
# Set remote = true if you want Wrangler to use the remote Artifacts service in local dev.
```

</WranglerConfig>

This exposes Artifacts as `env.ARTIFACTS` inside your Worker.

If you are using TypeScript, regenerate your local binding types:

<PackageManagers type="exec" pkg="wrangler" args="types" />

Wrangler adds an `Artifacts` type to your generated `worker-configuration.d.ts` file.

## 3. Write your Worker

Replace `src/index.ts` with the following code:

<TypeScriptExample filename="src/index.ts">

```ts
export default {
	async fetch(request, env) {
		const url = new URL(request.url);

		if (request.method === "POST" && url.pathname === "/repos") {
			// Read the repo name from the request body so the route is reusable.
			const body = await request.json().catch(() => ({}));

			const repoName = body.name ?? "starter-repo";

			// Create the repo and return the remote URL plus initial write token.
			const created = await env.ARTIFACTS.create(repoName);

			return Response.json({
				name: created.name,
				remote: created.remote,
				token: created.token,
			});
		}

		return new Response("Use POST /repos to create an Artifacts repo.", {
			status: 405,
			headers: { Allow: "POST" },
		});
	},
};
```

</TypeScriptExample>

This Worker creates an Artifacts repo and returns the remote URL and token your Git client needs to push and pull.

:::caution[Protect token-issuing routes]
This example omits authentication so it can focus on the Artifacts flow. In production, authorize the caller before creating repos or returning write tokens.
:::

For the demo, the Worker returns the initial write token. In production, mint short-lived read tokens for clone and pull flows, and mint write tokens only for operations that need push access.

## 4. Invoke your Worker to create a repo

Start local development:

<PackageManagers type="exec" pkg="wrangler" args="dev" />

Then, open a second terminal and send a request to your Worker to create a new Artifacts repo:

<Tabs>
	<TabItem label="Manual">

```bash
curl http://localhost:8787/repos \
  --header "Content-Type: application/json" \
  --data '{
    "name": "starter-repo"
  }'
```

Your Worker will call `env.ARTIFACTS.create()` and return three values you will need for Git operations:


```json
{
	"name": "starter-repo",
	"remote": "https://<ACCOUNT_ID>.artifacts.cloudflare.net/git/default/starter-repo.git",
	"token": "art_v1_0123456789abcdef0123456789abcdef01234567?expires=1760000000"
}
```
- `name`: the repo name. Must be unique within the namespace.
- `remote`: the Git remote URL for this repo. `<ACCOUNT_ID>` will be your actual Cloudflare account ID.
- `token`: a short-lived credential for Git operations. The token encodes its expiry directly in the `?expires=` suffix as a Unix timestamp.

Copy the `remote` and `token` values into local shell variables:

```sh
export ARTIFACTS_REMOTE="<PASTE_REMOTE_FROM_RESPONSE>"
export ARTIFACTS_TOKEN="<PASTE_TOKEN_FROM_RESPONSE>"
```

	</TabItem>
	<TabItem label="jq">

```bash
RESPONSE=$(curl --silent http://localhost:8787/repos \
  --header "Content-Type: application/json" \
  --data '{"name":"starter-repo"}')

export ARTIFACTS_REMOTE=$(printf '%s' "$RESPONSE" | jq -r '.remote')
export ARTIFACTS_TOKEN=$(printf '%s' "$RESPONSE" | jq -r '.token')
```

	</TabItem>

</Tabs>

## 5. Push your first commit with git

In the previous step, your Worker created an empty Artifacts repo. Now you will create a local Git repo, add a file, and push it to Artifacts — the same way you would push to any Git remote.


```sh
mkdir artifacts-demo
cd artifacts-demo
git init -b main
printf '# Artifacts demo\n' > README.md
git add README.md
git commit -m "Initial commit"
git remote add origin "$ARTIFACTS_REMOTE"
git -c http.extraHeader="Authorization: Bearer $ARTIFACTS_TOKEN" push -u origin main
```

The `-c http.extraHeader` flag passes the token as a request header, which keeps it out of your Git config and shell history.

If you need a self-contained remote URL for a short-lived command, build one from the token secret instead:

```sh
export ARTIFACTS_TOKEN_SECRET="${ARTIFACTS_TOKEN%%\?expires=*}"
export ARTIFACTS_AUTH_REMOTE="https://x:${ARTIFACTS_TOKEN_SECRET}@${ARTIFACTS_REMOTE#https://}"
git push "$ARTIFACTS_AUTH_REMOTE" HEAD:main
```

## 6. Pull the repo with a regular Git client

Clone the same repo into a second directory:

```sh
cd ..
git -c http.extraHeader="Authorization: Bearer $ARTIFACTS_TOKEN" clone "$ARTIFACTS_REMOTE" artifacts-clone
git -C artifacts-clone log --oneline -1
```

You should see the commit you pushed in the previous step.

You can also clone with a self-contained remote URL for a short-lived command:

```sh
git clone "$ARTIFACTS_AUTH_REMOTE" artifacts-clone
```

## 7. Deploy your Worker

Switch back to your Worker project directory: 
```sh
cd artifacts-worker
```

Deploy the Worker so you can create repos without running `wrangler dev`:

<PackageManagers type="exec" pkg="wrangler" args="deploy" />

Wrangler prints your `workers.dev` URL. Use the same `curl` request against that URL to create additional repos from production.

## Next steps

<LinkCard
	title="Workers binding reference"
	href="/artifacts/api/workers-binding/"
	description="Review the binding surface, return types, and method-by-method examples."
/>

<LinkCard
	title="Best practices"
	href="/artifacts/concepts/best-practices/"
	description="Use repo isolation, least-privilege tokens, and namespace separation effectively."
/>

<LinkCard
	title="Git protocol"
	href="/artifacts/api/git-protocol/"
	description="Use standard git-over-HTTPS remotes with either URL-based auth or `http.extraHeader`."
/>