Skip to content

Add a Deno demo for fetch-router - #11653

Open
kuboon wants to merge 5 commits into
remix-run:mainfrom
kuboon:claude/fetch-router-deno-demo-gfp448
Open

Add a Deno demo for fetch-router#11653
kuboon wants to merge 5 commits into
remix-run:mainfrom
kuboon:claude/fetch-router-deno-demo-gfp448

Conversation

@kuboon

@kuboon kuboon commented Jul 29, 2026

Copy link
Copy Markdown

A router created with createRouter() already exposes a fetch method, which is exactly the shape Deno.serve and deno serve expect. I have been running Remix 3 on Deno for a while now and it has been a really pleasant fit, so I would like to add a Deno demo next to the existing Bun and Node ones under packages/fetch-router/demos/.

It is the same blog application as the Node and Bun demos, so the three sit side by side and show that the router, middleware, and route helpers are runtime-agnostic. The difference is that on Deno there is no server entry point to write at all: deno serve does the rest.

  • Adds packages/fetch-router/demos/deno/ with the same routes, actions, and in-memory data as the Bun demo
  • The router is the default export, so deno serve picks up its fetch method and Deno owns the listener, the port, and graceful shutdown on SIGINT/SIGTERM
  • Serves public/ with staticFiles() from @remix-run/static-middleware instead of the hand-rolled file handler in the Bun demo, which also exercises Deno's node:fs/node:url compatibility
  • deno.json sets "nodeModulesDir": "manual" so Deno resolves @remix-run/* from the pnpm workspace's node_modules, and the tasks run with least-privilege permissions on port 44100
// deno.json
{
  "tasks": {
    "dev": "deno serve --watch --allow-read=./public --allow-env=CI,FORCE_COLOR,NO_COLOR,TERM --port 44100 app/router.ts",
    "start": "deno serve --allow-read=./public --allow-env=CI,FORCE_COLOR,NO_COLOR,TERM --port 44100 app/router.ts",
    "typecheck": "deno check"
  },
  "nodeModulesDir": "manual"
}

A few notes for reviewers:

The demo intentionally defines no typecheck or test script in its package.json, so pnpm -r typecheck and pnpm test stay green on machines without Deno installed. This matches the existing packages/multipart-parser/demos/deno. Type checking is available through deno task typecheck.
@types/node is a dev dependency because Deno needs it present in node_modules to resolve the node type reference that comes in through the @remix-run/* sources.
The permissions are deliberately narrow: static imports need no read permission, so --allow-read=./public covers the only runtime filesystem access, and --allow-env is limited to the four variables logger() inspects for color detection through @remix-run/terminal. deno serve provides its own network access, so no --allow-net is needed.
Tested with Deno 2.9.4.

claude added 3 commits July 27, 2026 01:13
Adds `packages/fetch-router/demos/deno`, a Deno counterpart to the existing
Node, Bun, and Cloudflare Workers fetch-router demos. It runs the same blog
application so the router, middleware, and route helpers are shown to be
runtime-agnostic, with only the server entry point being Deno-specific.

- `main.ts` serves `router.fetch` through `Deno.serve()` and shuts down
  gracefully on SIGINT/SIGTERM (SIGTERM is skipped on Windows, where Deno
  does not support it).
- `deno.json` sets `nodeModulesDir: "manual"` so Deno resolves the
  `@remix-run/*` packages from the pnpm workspace's `node_modules`, and
  defines dev/start/typecheck tasks with explicit permission flags.
- Static assets are served with `staticFiles()` from
  `@remix-run/static-middleware` rather than a hand-rolled file handler.
- The demo defines no `typecheck`/`test` package scripts, so recursive
  workspace runs stay green on machines without Deno installed.
A router is already a `{ fetch }` object, which is the default export shape
`deno serve` expects, so the demo does not need its own server entry point.
`main.ts` now re-exports the router as the default export and the `dev`/`start`
tasks use `deno serve --port 44100`, which also means Deno owns the listener
and the graceful shutdown on SIGINT/SIGTERM that `main.ts` implemented by hand.
`deno serve` provides its own network access, so the tasks no longer pass
`--allow-net`.
Static imports do not need read permission, so the only filesystem access the
demo makes at runtime is `staticFiles()` reading `./public`. Env access is
limited to the four variables the `logger()` middleware inspects for terminal
color detection.
@kuboon kuboon changed the title Claude/fetch router deno demo Add a Deno demo for fetch-router Jul 29, 2026
claude added 2 commits July 29, 2026 13:57
`deno serve` only needs a default export with a `fetch` method, and the router
module can provide that itself, so the demo no longer needs a separate entry
file. `app/router.ts` adds `export default router` and the tasks run
`deno serve app/router.ts`.
`deno check` with no arguments checks the whole project, so the typecheck task
covers `app/data.ts` and `app/routes.ts` as well, not only what the router
module imports.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants