Fastlike
June 9, 2026 ยท View on GitHub

Fastlike
Fastlike is a local development server for Fastly Compute (previously known as Compute@Edge) applications. It allows you to run and test your Fastly Compute WebAssembly programs locally without deploying to Fastly, making development faster and more efficient.
What is Fastlike?
Fastlike is a complete Go implementation of the Fastly Compute ABI that runs locally using WebAssembly. It emulates Fastly's runtime environment, allowing you to:
- Test Fastly Compute programs locally before deployment
- Debug issues without the deployment cycle
- Develop with hot-reloading capabilities
- Simulate backend services and configurations
Features
- Full ABI Compatibility: Implements 100% of the Fastly Compute ABI
- Local Development: Run Fastly Compute programs without deploying
- Multiple Backend Support: Configure multiple named backends
- Hot Reloading: Automatically reload WASM modules on file changes
- Dictionaries & Config Stores: Support for key-value lookups
- Caching: Full HTTP caching with surrogate keys
- ACL & Rate Limiting: Access control and rate limiting support
- Secure Secret Handling: Secure credential management
- KV Store Support: Object storage with async operations
- Image Optimization Hooks: Transform images on-the-fly
- Built-in Profiler: Capture hostcall timings, backend waterfalls, native CPU samples, and deep-mode body/cache/header/memory counters, served through a browser viewer. See docs/profiling.md.
Profiling
Fastlike ships with a built-in profiler. Pass -profile-ui localhost:6060 and open the viewer in your browser to inspect hostcall timings, backend waterfalls, optional native CPU samples, and (in deep mode) body byte counters, cache hit/miss rates, store access counts, header summaries, and the wasm linear memory curve. The full operator guide lives in docs/profiling.md.
Installation
Prerequisites
- Go 1.23 or later
Install via Go
go install fastlike.dev/cmd/fastlike@latest
Build from Source
# Clone the repository (if you have the source code)
# If you just want to install, use: go install fastlike.dev/cmd/fastlike@latest
git clone https://github.com/fastlike/fastlike.git
cd fastlike
# Build and install
make build
# Binary will be available at ./bin/fastlike
# Or install to GOPATH/bin
make install
Getting Started
1. Get a Fastly Compute WASM Program
You'll need a Fastly Compute compatible WebAssembly program. The easiest way is using Fastly CLI:
# Create a new project
fastly compute init my-project
cd my-project
# Build the WASM binary
fastly compute build
# WASM file will be at bin/main.wasm
2. Run with a Backend
Start Fastlike with your WASM program and a backend service:
# Run with a local backend on port 8000
fastlike -wasm bin/main.wasm -backend localhost:8000
# Or with a named backend
fastlike -wasm bin/main.wasm -backend api=localhost:8000 -bind localhost:5000
3. Test Your Application
Once running, make requests to your local Fastlike server:
curl http://localhost:5000/
Configuration Options
Basic Options
# Specify custom bind address
fastlike -wasm my-program.wasm -backend localhost:8000 -bind localhost:8080
# Enable verbose logging (0, 1, or 2 levels)
fastlike -wasm my-program.wasm -backend localhost:8000 -v 2
# Enable hot reloading on SIGHUP
fastlike -wasm my-program.wasm -backend localhost:8000 -reload
Multiple Backends
Configure multiple named backends for complex routing:
fastlike -wasm my-program.wasm \
-backend api=localhost:8000 \
-backend static=localhost:8080 \
-backend images=localhost:9000
Simulating Unreliable Backends
Append @N to a backend address to simulate flakiness, where N is the percentage of requests that should reach the upstream successfully. The remaining requests are answered with a synthetic 502, identical in shape to the response Fastlike emits when a real upstream is unreachable. This is handy for exercising error paths in your guest program without actually taking a backend down.
# api responds normally for roughly half of requests, the rest get a 502
fastlike -wasm my-program.wasm -backend api=localhost:8000@50
# cdn always appears down
fastlike -wasm my-program.wasm -backend cdn=localhost:9000@0
# default catch-all backend with simulated reliability
fastlike -wasm my-program.wasm -backend localhost:8000@75
The suffix is recognized only when it is purely numeric and in the 0..100 range, so URLs that legitimately contain @ (for example http://user:pass@host) are left alone. A trailing @<digits> outside 0..100 is rejected at startup. The same behavior is available programmatically through fastlike.WithUnreliableBackend and fastlike.WithUnreliableDefaultBackend.
The @N suffix also drives what the is_healthy hostcall reports for the backend, since health and reliability are the same axis: a backend with no suffix reports unknown (the default, matching a backend without health checks), @0 reports unhealthy, and any positive uptime reports healthy. This lets you exercise guest failover logic without a separate health flag.
Faking Valid Fastly Keys
Some guest programs gate purge or admin endpoints on a valid Fastly-Key header via the is_valid() hostcall. Pass -fake-fastly-key (repeatable) to declare header values that should be treated as valid; any request whose Fastly-Key header matches reports valid, everything else reports invalid.
fastlike -wasm my-program.wasm -backend localhost:8000 -fake-fastly-key test-key -fake-fastly-key another-key
With no keys configured the hostcall always reports invalid, matching production for an unauthenticated request. The same behavior is available programmatically through fastlike.WithFakeValidFastlyKeys.
Dictionaries and Config Stores
Use JSON files for key-value lookups:
# Create a config file
echo '{"api_key": "secret123", "version": "1.0.0"}' > config.json
# Use as a dictionary
fastlike -wasm my-program.wasm -backend localhost:8000 -dictionary config=config.json
# Or use as a config store
fastlike -wasm my-program.wasm -backend localhost:8000 -config-store config=config.json
The file should contain a JSON object with string keys and values:
{
"key1": "value1",
"key2": "value2",
"api_endpoint": "https://api.example.com"
}
KV Stores
Load KV store data from JSON files or create empty stores:
# Create a KV store with initial data
fastlike -wasm my-program.wasm -backend localhost:8000 -kv mystore=data.json
# Create an empty KV store
fastlike -wasm my-program.wasm -backend localhost:8000 -kv mystore
KV store JSON supports simple string values or objects with body and metadata:
{
"simple_key": "simple value",
"key_with_metadata": {
"body": "the value content",
"metadata": "optional metadata"
}
}
Secret Stores
Store sensitive credentials in JSON files:
fastlike -wasm my-program.wasm -backend localhost:8000 -secret-store secrets=secrets.json
Secret store JSON format (string key-value pairs):
{
"api_key": "sk-live-xxxxx",
"database_password": "supersecret"
}
Access Control Lists (ACLs)
Configure IP-based access control:
fastlike -wasm my-program.wasm -backend localhost:8000 -acl blocklist=acl.json
ACL JSON format with CIDR prefixes and actions:
{
"entries": [
{"prefix": "192.168.0.0/16", "action": "ALLOW"},
{"prefix": "10.0.0.0/8", "action": "ALLOW"},
{"prefix": "172.16.0.0/12", "action": "BLOCK"}
]
}
Geolocation
Provide custom IP-to-location mappings:
fastlike -wasm my-program.wasm -backend localhost:8000 -geo geo.json
Geo JSON maps IP addresses or CIDRs to location data:
{
"192.168.1.0/24": {
"city": "San Francisco",
"country_code": "US",
"region": "CA",
"latitude": 37.7749,
"longitude": -122.4194
},
"10.0.0.1": {
"city": "New York",
"country_code": "US"
}
}
Log Endpoints
Configure named log endpoints for your application:
# Log to stdout
fastlike -wasm my-program.wasm -backend localhost:8000 -logger access
# Log to a file
fastlike -wasm my-program.wasm -backend localhost:8000 -logger access=/var/log/access.log
Compliance Region
Set the compliance region for data locality requirements:
fastlike -wasm my-program.wasm -backend localhost:8000 -compliance-region us-eu
Hot Reloading
Enable hot reloading to automatically reload your WASM module when you make changes:
# Start with reload enabled
fastlike -wasm my-program.wasm -backend localhost:8000 -reload
# In another terminal, send SIGHUP to reload
kill -SIGHUP $(pgrep fastlike)
# Or if you know the process ID: kill -SIGHUP <pid>
Testing and Development
Make Commands
The project includes a Makefile with helpful commands:
# Build the binary
make build
# Run all tests
make test
# Build test WASM programs (for development)
make build-test-wasm
# Run with Make (requires WASM and BACKEND variables)
make run WASM=my-program.wasm BACKEND=localhost:8000
# Run with arguments
make run WASM=my-program.wasm BACKEND=localhost:8000 ARGS='-v 2'
Verbose Mode per Request
For debugging specific requests, add the fastlike-verbose header:
curl -H "fastlike-verbose: 1" http://localhost:5000/
This enables verbose logging for just that request.
Example Usage
Simple Setup
# Start a simple backend server
python3 -m http.server 8000 &
# Run Fastlike with your WASM program
fastlike -wasm my-program.wasm -backend localhost:8000 -bind localhost:5000
# Test it
curl http://localhost:5000/
Complex Multi-Backend Setup
# Start multiple backend services
python3 -m http.server 8000 & # Static files
node app.js 8080 & # API server
npx serve public/ 9000 & # Another service
# Run Fastlike with multiple backends and stores
fastlike -wasm my-program.wasm \
-backend static=localhost:8000 \
-backend api=localhost:8080 \
-backend images=localhost:9000 \
-config-store config=config.json \
-secret-store secrets=secrets.json \
-kv cache=cache.json \
-acl blocklist=acl.json \
-geo geo.json \
-logger access \
-bind localhost:5000
# Now your WASM program can use all configured backends and stores
Development Workflow with Hot Reloading
# Terminal 1: Start Fastlike with hot reload
fastlike -wasm my-program.wasm -backend localhost:8000 -reload
# Terminal 2: Build and reload when changes occur
while inotifywait -e modify my-project/src/*; do
cd my-project && fastly compute build
kill -SIGHUP $(pgrep fastlike)
done
# Terminal 3: Test continuously
watch -n 1 curl -s http://localhost:5000/
Advanced Features
Profiler and Trace Viewer
Fastlike's built-in profiler records every guest request and serves traces through a read-only HTTP listener. Start it with -profile-ui <addr>, switch to deep mode with -profile-mode deep for body/cache/header/memory metrics, or enable native CPU sampling with -profile-native. The full reference, including security gates, deep-mode caveats, and the macOS and Linux native sampling setup, is documented in docs/profiling.md.
Custom Logging
Enable verbose logging to see all ABI calls:
# Persistent verbose logging
fastlike -wasm my-program.wasm -backend localhost:8000 -v 2
# Per-request verbose logging
curl -H "fastlike-verbose: 1" http://localhost:5000/
Backend Configuration
Support for named backend configurations. Complex backend configurations with timeouts, SSL, and more are available through the Go API but not through the CLI. Reliability simulation (the @N suffix described above) is the one exception, and is exposed on both the CLI and the Go API.
Cache Support
Full HTTP caching support with request collapsing and surrogate key management - all working locally.
Request Loops Prevention
Fastlike adds "Fastlike" to the cdn-loop header to prevent infinite request loops. If a loop is detected, it returns a 508 Loop Detected error.