React Router ​
This guide demonstrates how to deploy a React Router (formerly Remix.js) application to Cloudflare with Alchemy.
Create a new React Router Project ​
Start by creating new React Router project using the Cloudflare template.
NOTE
This template assumes you're using wrangler. We will adapt it to Alchemy (and learn some Alchemy concepts along the way).
bun create cloudflare@latest my-react-router-app --framework=react-router
npm create cloudflare@latest -- my-react-router-app --framework=react-router
pnpm create cloudflare@latest my-react-router-app --framework=react-router
yarn create cloudflare my-react-router-app --framework=react-router
Remove Unnecessary files ​
Cloudflare's React Router template uses wrangler.jsonc
and wrangler types
to generate types which are not used by Alchemy. Let's remove these.
cd ./my-react-router-app
rm -rf worker-configuration.d.ts wrangler.jsonc
Install Dependenices ​
Now install the alchemy and cloudflare dependencies.
bun add alchemy cloudflare
bun add -D @cloudflare/workers-types
npm install alchemy cloudflare
bun install --save-dev @cloudflare/workers-types
pnpm add alchemy cloudflare
pnpm add -D @cloudflare/workers-types
yarn add alchemy cloudflare
yarn add -D @cloudflare/workers-types
Create alchemy.run.ts
​
alchemy.run.ts
can be thought of as kinda like the wrangler.jsonc
except in pure TypeScript code.
Let's create it and use the ReactRouter
from alchemy/cloudflare
to build and deploy our React Router project.
/// <reference types="node" />
import alchemy from "alchemy";
import { ReactRouter } from "alchemy/cloudflare";
const app = await alchemy("my-react-router-app", {
stage: process.env.USER ?? "dev",
phase: process.argv.includes("--destroy") ? "destroy" : "up",
});
export const website = await ReactRouter("website", {
main: "./workers/app.ts",
command: "bun run build",
});
console.log({
url: website.url,
});
await app.finalize();
Configure Alchemy Types ​
As mentioned, Alchemy does not use wrangler types
to generate worker-configuration.d.ts
types. Instead, types are inferred from your Alchemy code directly.
To configure this, first create ./workers/env.ts
with the following content:
import type { website } from "../alchemy.run.ts";
export type CloudflareEnv = typeof website.Env;
declare global {
type Env = CloudflareEnv
}
declare module "cloudflare:workers" {
namespace Cloudflare {
export interface Env extends CloudflareEnv {}
}
}
Then, update tsconfig.json
to include ./workers/env.ts
and @cloudflare/workers-types
as global types:
{
"files": [],
"references": [
{ "path": "./tsconfig.node.json" },
{ "path": "./tsconfig.cloudflare.json" }
],
"compilerOptions": {
"checkJs": true,
"verbatimModuleSyntax": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
// register Alchemy and Cloudflare types globally
"types": ["./workers/env.ts", "@cloudflare/workers-types"]
}
}
Log in to Cloudflare ​
Before you can deploy, you need to authenticate by running wrangler login
.
bun wrangler login
npx wrangler login
pnpm wrangler login
yarn wrangler login
TIP
Alchemy will by default try and use your wrangler OAuth token and Refresh Token to connect but see the Cloudflare Auth for other methods.
Deploy ​
Now we can run and deploy our Alchemy stack:
bun ./alchemy.run
npx tsx ./alchemy.run
pnpm tsx ./alchemy.run
yarn tsx ./alchemy.run
It will log out the URL of your new React Router website hosted on Cloudflare:
{
url: "https://website.${your-sub-domain}.workers.dev",
}
Destroy ​
For illustrative purposes, let's destroy the Alchemy stack.
bun ./alchemy.run.ts --destroy
You're done! Happy React-Router'ing 😎