This site is not affiliated with or endorsed by Cloudflare, Inc. It showcases deployable experiments across most Cloudflare products.
Storage & Data

Artifact Workspace

Versioned filesystem-style artifact workspace on R2 - store, list, and retrieve build or agent artifacts like a remote FS

Artifacts-style versioned filesystem workspace. Cloudflare Artifacts bindings are still evolving, so this experiment uses an R2 bucket behind a typed ArtifactStore interface until a stable Artifacts binding is available.

Features

  • PUT /files?path= - store text content
  • GET /files?path= - read file content
  • GET /files/list?prefix= - list paths
  • DELETE /files?path= - delete a file

API Reference

Path rules

  • Max length 256
  • Allowed characters: alphanumeric, /, _, -, .
  • No .. segments

PUT /files

Store text content at a path. Body is raw text.

path string (required)

Example Request

curl -X PUT "https://your-worker.workers.dev/files?path=notes/hello.txt" \
  -H "Content-Type: text/plain" \
  -d "hello world"

Success Response

{
  "path": "notes/hello.txt",
  "stored": true
}

GET /files

Returns the file body as text/plain, or 404 if missing.

path string (required)

Example Request

curl "https://your-worker.workers.dev/files?path=notes/hello.txt"

GET /files/list

List stored paths, optionally filtered by prefix.

prefix string (optional)

Example Request

curl "https://your-worker.workers.dev/files/list?prefix=notes/"

Success Response

{
  "files": [{ "path": "notes/hello.txt" }],
  "prefix": "notes/"
}

DELETE /files

path string (required)

Example Request

curl -X DELETE "https://your-worker.workers.dev/files?path=notes/hello.txt"

Success Response

{
  "path": "notes/hello.txt",
  "deleted": true
}

Error Codes

  • 400 - Missing or invalid path/prefix (INVALID_PATH)
  • 404 - File does not exist (NOT_FOUND)

Use Cases

  • Learn Artifacts-style workspace patterns on Workers
  • Store generated code, reports, or build outputs at the edge
  • Swap R2 for a future native Artifacts binding via ArtifactStore
  • Prototype multi-tenant file APIs with path prefixes

Limitations

  • Uses R2 as a stand-in; not the final Artifacts product API
  • Text bodies only in this demo
  • Path validation rejects .. and unusual characters
  • No authentication or per-user isolation beyond path conventions

Use in your project

Copy these files into an existing Worker. Prefer Deployment to try the full experiment first. Source: apps/experiments/artifact-workspace.

DependenciesNoneBindingsR2PlatformWorkers runtime
import { MAX_PATH_LENGTH, PATH_PATTERN } from "../constants/defaults";import type { ArtifactStore } from "../types/env";export function validatePath(input: string | undefined): string | null {  if (!input || typeof input !== "string") return null;  const trimmed = input.trim();  if (!trimmed || trimmed.length > MAX_PATH_LENGTH) return null;  if (trimmed.includes("..")) return null;  if (!PATH_PATTERN.test(trimmed)) return null;  return trimmed;}/** R2-backed ArtifactStore for the Artifacts-style workspace demo. */export function createR2ArtifactStore(bucket: R2Bucket): ArtifactStore {  return {    async put(path: string, data: string | ArrayBuffer): Promise<void> {      await bucket.put(path, data);    },    async get(path: string): Promise<ReadableStream | null> {      const object = await bucket.get(path);      return object?.body ?? null;    },    async list(prefix?: string): Promise<{ path: string }[]> {      const listed = await bucket.list({ prefix: prefix || undefined });      return listed.objects.map((obj) => ({ path: obj.key }));    },    async delete(path: string): Promise<void> {      await bucket.delete(path);    },  };}

Deployment

Click the deploy button

Deploy to Cloudflare Workers

Configure R2

Create the R2 bucket artifact-workspace (or update wrangler.json) and bind it as ARTIFACTS.

Test your deployment

curl -X PUT "https://your-worker.workers.dev/files?path=notes/hello.txt" \
  -H "Content-Type: text/plain" \
  -d "hello world"

Local Development

cd apps/experiments/artifact-workspace
npm install
npm run dev
curl -X PUT "http://localhost:8787/files?path=notes/hello.txt" \
  -H "Content-Type: text/plain" \
  -d "hello world"

Configuration

wrangler.json declares:

  • R2 bucket ARTIFACTS → artifact-workspace

When a stable Artifacts binding lands, the intended shape is artifacts: [{ binding: "ARTIFACTS", name: "workspace" }]. The ArtifactStore interface isolates route code from the backend.

Cloudflare Features Used

  • Workers - Edge compute runtime
  • R2 - Object storage standing in for Artifacts

On this page