React Router
Step-by-step guide to deploying a React Router (formerly Remix) application to Cloudflare Workers using Alchemy.
This guide demonstrates how to deploy a React Router (formerly Remix.js) application to Cloudflare with Alchemy.
Start by creating a new React Router project using Alchemy:
bunx alchemy create my-react-router-app --template=react-routercd my-react-router-appnpx alchemy create my-react-router-app --template=react-routercd my-react-router-apppnpm dlx alchemy create my-react-router-app --template=react-routercd my-react-router-appyarn dlx alchemy create my-react-router-app --template=react-routercd my-react-router-appBefore you can deploy, you need to authenticate by running alchemy login.
bun alchemy loginnpx alchemy loginpnpm alchemy loginyarn alchemy login::: tip Alchemy will by default try and use your wrangler OAuth token and Refresh Token to connect but see the Cloudflare for other methods.
Deploy
Section titled “Deploy”Now we can run and deploy our Alchemy stack:
bun run deploynpm run deploypnpm run deployyarn run deployIt will log out the URL of your new React Router website hosted on Cloudflare:
{ url: "https://website.${your-sub-domain}.workers.dev",}bun run devnpm run devpnpm run devyarn run devDestroy
Section titled “Destroy”For illustrative purposes, let’s destroy the Alchemy stack:
bun run destroynpm run destroypnpm run destroyyarn run destroyWhat files are created
Section titled “What files are created”Alchemy requires a locally set password to encrypt Secrets that are stored in state. Be sure to change this.
ALCHEMY_PASSWORD=change-mealchemy.run.ts
Section titled “alchemy.run.ts”The alchemy.run.ts file contains your infrastructure setup:
/// <reference types="@types/node" />
import alchemy from "alchemy";import { ReactRouter } from "alchemy/cloudflare";
const app = await alchemy("my-react-router-app");
export const worker = await ReactRouter("website");
console.log({ url: worker.url,});
await app.finalize();types/env.d.ts
Section titled “types/env.d.ts”The types/env.d.ts file provides type-safe access to Cloudflare bindings:
// This file infers types for the cloudflare:workers environment from your Alchemy Worker.// @see https://alchemy.run/concepts/bindings/#type-safe-bindings
import type { worker } from "../alchemy.run.ts";
export type CloudflareEnv = typeof worker.Env;
declare global { type Env = CloudflareEnv;}
declare module "cloudflare:workers" { namespace Cloudflare { export interface Env extends CloudflareEnv {} }}tsconfig.node.json
Section titled “tsconfig.node.json”The CLI updated the tsconfig.node.json to include alchemy.run.ts and register @cloudflare/workers-types + types/env.d.ts globally
{ "extends": "./tsconfig.json", "include": [ "vite.config.ts", // ensure our types and alchemy.run.ts are included "types/**/*.ts", "alchemy.run.ts" ], "compilerOptions": { "composite": true, "strict": true, // register cloudflare types and our Env types globally "types": ["@cloudflare/workers-types", "./types/env.d.ts"], "lib": ["ES2022"], "target": "ES2022", "module": "ES2022", "moduleResolution": "bundler" }}vite.config.ts
Section titled “vite.config.ts”Use the alchemy() function to develop and deploy for Cloudflare Workers:
import { reactRouter } from "@react-router/dev/vite";import alchemy from "alchemy/cloudflare/react-router";import { defineConfig } from "vite";import tsconfigPaths from "vite-tsconfig-paths";
export default defineConfig({ plugins: [ alchemy(), reactRouter(), tsconfigPaths({ root: "." }), ],});