Documentation Index Fetch the complete documentation index at: https://mintlify.com/remix-run/remix/llms.txt
Use this file to discover all available pages before exploring further.
Cloudflare Workers is a serverless platform that runs your code at the edge, close to your users worldwide. Remix applications work natively on Workers thanks to their web standards-based API.
Prerequisites
A Cloudflare account
Wrangler CLI installed (npm install -g wrangler)
A Remix application ready to deploy
Project Setup
Initialize a Workers project:
Create a wrangler.toml configuration:
name = "remix-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[ build ]
command = "npm run build"
# Environment variables
[ vars ]
ENVIRONMENT = "production"
Worker Entry Point
Create your Workers entry point:
import router from './router'
export default {
async fetch ( request : Request , env : Env , ctx : ExecutionContext ) : Promise < Response > {
try {
return await router . fetch ( request )
} catch ( error ) {
return new Response ( 'Internal Server Error' , { status: 500 })
}
} ,
}
Router Configuration
Your router works the same as on Node.js:
import { createRouter } from 'remix/fetch-router'
import { route } from 'remix/fetch-router/routes'
let routes = route ({
home: '/' ,
api: {
users: '/api/users' ,
},
})
let router = createRouter ()
router . map ( routes , {
actions: {
home () {
return new Response ( 'Hello from the edge!' )
},
api: {
actions: {
users () {
return Response . json ({ users: [] })
},
},
},
},
})
export default router
Development
Run locally with Wrangler:
Deployment
Deploy to Cloudflare:
Environment Variables & Secrets
Set environment variables:
wrangler secret put DATABASE_URL
wrangler secret put SESSION_SECRET
Access in your worker:
export default {
async fetch ( request : Request , env : Env ) : Promise < Response > {
let databaseUrl = env . DATABASE_URL
let sessionSecret = env . SESSION_SECRET
// Use in your application
} ,
}
Durable Objects
For stateful applications, use Durable Objects:
export class Counter {
state : DurableObjectState
count : number = 0
constructor ( state : DurableObjectState ) {
this . state = state
}
async fetch ( request : Request ) {
this . count ++
return Response . json ({ count: this . count })
}
}
KV Storage
Bind KV namespaces in wrangler.toml:
[[ kv_namespaces ]]
binding = "CACHE"
id = "your-namespace-id"
Use in your application:
export default {
async fetch ( request : Request , env : Env ) : Promise < Response > {
await env . CACHE . put ( 'key' , 'value' )
let value = await env . CACHE . get ( 'key' )
return Response . json ({ value })
} ,
}
D1 Database
For SQL databases, use Cloudflare D1:
[[ d1_databases ]]
binding = "DB"
database_name = "remix-db"
database_id = "your-database-id"
export default {
async fetch ( request : Request , env : Env ) : Promise < Response > {
let result = await env . DB . prepare ( 'SELECT * FROM users' ). all ()
return Response . json ( result )
} ,
}
Limitations
CPU time: 50ms on free tier, more on paid plans
No Node.js built-ins (use web standards)
Request size: 100MB max
Best Practices
Keep workers lightweight
Use KV for caching
Minimize database queries
Use Durable Objects for state
Leverage edge caching
Web Standards Why Remix works perfectly on Workers
Fetch Router Router API reference