cloudfront-functions — CloudFront Functions & KeyValueStore

A zero-dependency, in-process emulator for the AWS CloudFront Functions control plane and CloudFront KeyValueStore (with a simple data-plane key/value API).

PropertyValue
Port4713
ProtocolREST / XML (+ JSON data plane)
API Version2020-05-31
HealthGET /_parlel/health
ResetPOST /_parlel/reset

Default connection

AWS_ENDPOINT_URL=http://127.0.0.1:4713
AWS_REGION=us-east-1
AWS_ACCESS_KEY_ID=parlel
AWS_SECRET_ACCESS_KEY=parlel

Supported operations

OperationPath
CreateFunctionPOST /2020-05-31/function
ListFunctionsGET /2020-05-31/function
DescribeFunctionGET /2020-05-31/function/{name}
PublishFunctionPOST /2020-05-31/function/{name}/publish
TestFunctionPOST /2020-05-31/test-function
DeleteFunctionDELETE /2020-05-31/function/{name}
CreateKeyValueStorePOST /2020-05-31/key-value-store
ListKeyValueStoresGET /2020-05-31/key-value-store

KeyValueStore data plane (parlel extension)

OperationPath
PutKeyPUT /2020-05-31/key-value-store/{name}/keys/{k}
GetKeyGET /2020-05-31/key-value-store/{name}/keys/{k}
DeleteKeyDELETE /2020-05-31/key-value-store/{name}/keys/{k}
ListKeysGET /2020-05-31/key-value-store/{name}/keys

TestFunction actually executes the function code with a synthetic event, returning FunctionOutput, so you can validate handler logic.

SDK usage example

import {
  CloudFrontClient,
  CreateFunctionCommand,
  TestFunctionCommand,
} from "@aws-sdk/client-cloudfront";

const cf = new CloudFrontClient({
  endpoint: "http://127.0.0.1:4713",
  region: "us-east-1",
  credentials: { accessKeyId: "parlel", secretAccessKey: "parlel" },
});

await cf.send(
  new CreateFunctionCommand({
    Name: "redirect",
    FunctionConfig: { Comment: "", Runtime: "cloudfront-js-2.0" },
    FunctionCode: Buffer.from(
      "function handler(event){ event.request.uri='/index.html'; return event.request; }",
    ),
  }),
);

Access via MCP / preview URL

Point any AWS SDK or MCP tool at the allocated preview URL via AWS_ENDPOINT_URL.

Surface coverage

This emulator faithfully replicates the API surface most application code and agents exercise. Anything below the supported lines is either an intentional design choice for a fast, zero-cost local emulator (✓ By design) or a candidate for a future release (⟳ Roadmap) — never a silent inaccuracy.

Legend: ✅ fully supported · ◐ accepted (stored, not strictly enforced) · ✓ by design · ⟳ on the roadmap.

AreaLimitation
RuntimeTestFunction uses node:Function, not the real CF runtime
UpdateFunctionNot implemented
ETag concurrencyETag returned but not enforced on update/publish
AssociationsFunction-to-distribution associations not tracked
StateIn-memory only; lost on restart
<!-- parlel:testenv:start -->

Configuration — test.env

Copy these into your test.env (used by the bridge sidecar flow). Tokens are Parlel's seeded test credentials — any non-empty value is accepted by the emulator, so you rarely need to change them. Swap in real credentials only when pointing at the live service in prod.env.

AWS_ACCESS_KEY_ID=parlel
AWS_SECRET_ACCESS_KEY=parlel
AWS_REGION=us-east-1
AWS_ENDPOINT_URL=http://parlel-bridge:4713
<!-- parlel:testenv:end -->