How use Remix + Hono
Hono - is a small, simple, and ultrafast web framework for the Edges. It works on any JavaScript runtime: Cloudflare Workers, Fastly Compute, Deno, Bun, Vercel, Netlify, AWS Lambda, Lambda@Edge, and Node.js.
In this case we use hono middlewares with remix and cloudflare.
Setup Hono
How to implement remix-hono
lib for remix app. First we have to install npm i remix-hono
and create the following file:
// server/index.ts
import { EnvSchema } from "./env";
import { logDevReady } from "@remix-run/cloudflare";
import * as build from "@remix-run/dev/server-build";
import { Hono } from "hono";
// You can also use it with other runtimes
import { handle } from "hono/cloudflare-pages";
import { remix } from "remix-hono/handler";
import { basicAuth } from "hono/basic-auth";
if (process.env.NODE_ENV === "development") logDevReady(build);
/* type your Cloudflare bindings here */
type Bindings = {};
/* type your Hono variables (used with c.get/c.set) here */
type Variables = {};
type ContextEnv = { Bindings: Bindings; Variables: Variables };
const server = new Hono<ContextEnv>();
server.use("*", basicAuth({ username: "hono", password: "remix" }));
server.use(
"*",
remix({
build,
mode: process.env.NODE_ENV as "development" | "production",
getLoadContext(ctx) {
const env = EnvSchema.parse(ctx.env);
const response = {
env,
db: ctx.env.DB,
};
return response;
},
})
);
export const onRequest = handle(server);
Setup Envs variables
Our environment variables will be in the file .dev.vars
for example:
DB="postgresql://saasa:url-database/sarasa?sslmode=require"
Then we create a env.ts
file
// server/env.ts
import { z } from "zod";
export const EnvSchema = z.object({
DB: z.string().min(1),
});
export type Env = z.infer<typeof EnvSchema>;
Setup Remix config
For our remix app to start with hono we have to change the server in remix.config.js
:
/** @type {import('@remix-run/dev').AppConfig} */
export default {
ignoredRouteFiles: ["**/*.css"],
server: "./server/index.ts", // run with hono config
watchPaths: ["./server/**/*.ts"],
serverBuildPath: "functions/[[path]].js",
serverConditions: ["worker"],
serverDependenciesToBundle: "all",
serverMainFields: ["browser", "module", "main"],
serverMinify: true,
serverModuleFormat: "esm",
serverPlatform: "neutral",
serverNodeBuiltinsPolyfill: { modules: {} },
};
Using Envs
And that is the basic configuration, if you want to use your environment variable (in this case db). You can do something like this:
export const loader = async ({ context }: LoaderFunctionArgs) => {
const hotels = await queryHotels(context);
return json({ hotels });
};
queries file:
import { neon } from "@neondatabase/serverless";
import { AppLoadContext } from "@remix-run/cloudflare";
import { database } from "db/db.server";
export async function queryHotels(context: AppLoadContext) {
const db = database(neon(context.db as string));
const hotels = await db.query.hotels.findMany();
return hotels;
}
and databse config:
export function database(neon: any) {
return drizzle(neon, {
schema: {
hotels: hotelsTable,
},
});
}
End
Thank you very much for reading and I hope you found it helpful.