glen icon indicating copy to clipboard operation
glen copied to clipboard

wrangler dev fails with "node:fs" import error when using glen on Cloudflare Workers

Open Comamoca opened this issue 4 months ago β€’ 0 comments

When creating a web server for Cloudflare Workers with glen, I encounter the following error when running wrangler dev to start the development server.

Environment

  • Gleam 1.12.0
  • Node.js v22.17.0
  • wrangler 4.26.1
  • OS: NixOS

Problem Description

Following the "Bring-your-own server" section of the glen README, I created a web server.

However, when running wrangler dev, I get the error:

The package "node:stream" wasn't found on the file system but is built into node.

The full error log is as follows:

--- 2025-08-06T23:22:38.762Z debug
πŸͺ΅  Writing logs to "/home/coma/.wrangler/logs/wrangler-2025-08-06_23-22-38_628.log"
---

--- 2025-08-06T23:22:38.762Z log
[90m[39m
[90mCloudflare collects anonymous telemetry about your usage of Wrangler. Learn more at https://github.com/cloudflare/workers-sdk/tree/main/packages/wrangler/telemetry.md[39m
---

--- 2025-08-06T23:22:38.765Z debug
Metrics dispatcher: Source Key not provided. Be sure to initialize before sending events {"deviceId":"2aab41ed-4f90-4cc2-a776-c1f5436a5974","event":"wrangler command started","timestamp":1754522558765,"properties":{"amplitude_session_id":1754522558761,"amplitude_event_id":0,"wranglerVersion":"4.26.1","osPlatform":"Linux","osVersion":"#1-NixOS SMP PREEMPT_DYNAMIC Thu Jul 17 16:37:24 UTC 2025","nodeVersion":22,"isFirstUsage":false,"configFileType":"toml","isCI":false,"isPagesCI":false,"isWorkersCI":false,"isInteractive":true,"hasAssets":false,"argsUsed":[],"argsCombination":"","command":"wrangler dev","args":{"xJsonConfig":true,"j":true,"latest":true,"noBundle":false,"remote":false,"r":false,"testScheduled":false,"xVectorizeBindToProd":false,"xImagesLocalMode":false}}}
---

--- 2025-08-06T23:22:38.767Z debug
.env file not found at ".env". Continuing... For more details, refer to https://developers.cloudflare.com/workers/wrangler/system-environment-variables/
---

--- 2025-08-06T23:22:38.776Z log

 ⛅️ wrangler 4.26.1 (update available [32m4.28.0[39m)
[38;5;214m─────────────────────────────────────────────[39m
---

--- 2025-08-06T23:22:38.787Z log
[34m[custom build][39m Running: gleam build
---

--- 2025-08-06T23:22:38.834Z log
[31m[custom build][39m    Compiled in 0.02s
---

--- 2025-08-06T23:22:38.834Z log
[31m[custom build][39m 
---

--- 2025-08-06T23:22:38.874Z debug
.env file not found at ".dev.vars". Continuing... For more details, refer to https://developers.cloudflare.com/workers/wrangler/system-environment-variables/
---

--- 2025-08-06T23:22:38.918Z log
The file src changed, restarting build...
---

--- 2025-08-06T23:22:38.918Z log
[34m[custom build][39m Running: gleam build
---

--- 2025-08-06T23:22:38.954Z log
[31m[custom build][39m    Compiled in 0.01s
---

--- 2025-08-06T23:22:38.954Z log
[31m[custom build][39m 
---

--- 2025-08-06T23:22:39.250Z warn
[33mβ–² [43;33m[[43;30mWARNING[43;33m][0m [1mThe package "node:stream" wasn't found on the file system but is built into node.[0m

  Your Worker may throw errors at runtime unless you enable the "nodejs_compat" compatibility flag.
  Refer to [4mhttps://developers.cloudflare.com/workers/runtime-apis/nodejs/[0m for more details. Imported
  from:
   - [34mbuild/dev/javascript/glen/glen.ffi.mjs[39m


---

--- 2025-08-06T23:22:39.251Z warn
[33mβ–² [43;33m[[43;30mWARNING[43;33m][0m [1mThe package "node:fs" wasn't found on the file system but is built into node.[0m

  Your Worker may throw errors at runtime unless you enable the "nodejs_compat" compatibility flag.
  Refer to [4mhttps://developers.cloudflare.com/workers/runtime-apis/nodejs/[0m for more details. Imported
  from:
   - [34mbuild/dev/javascript/glen/glen.ffi.mjs[39m


---

--- 2025-08-06T23:22:39.252Z debug
RemoteRuntimeController teardown beginning...
---

--- 2025-08-06T23:22:39.253Z debug
RemoteRuntimeController teardown complete
---

--- 2025-08-06T23:22:39.255Z log
[2mβŽ” Starting local server...[22m
---

--- 2025-08-06T23:22:39.262Z debug
[InspectorProxyWorker] handleProxyControllerIncomingMessage {"type":"reloadStart"}
---

The source code that reproduces this problem is published here:

https://github.com/Comamoca/share/tree/main/gleam_glen_nodefs_error

A simplified example of the code is as follows:

// glen_nodefs_error.gleam
import gleam/javascript/promise
import glen
import glen/status

pub fn handle_req(_req) {
  "On a Cloudflare worker!"
  |> glen.html(status.ok)
  |> promise.resolve
}

About the Problem

This issue occurs when running on Cloudflare Workers.

I have tried enabling the nodejs_compat flag by adding the following to wrangler.toml, but the problem remains:

name = "glen_nodefs_error"
main = "build/dev/javascript/glen_nodefs_error/index.js"
compatibility_date = "2023-09-22"

[build]
command = "gleam build"

According to Cloudflare’s documentation, file system APIs are not yet supported: https://developers.cloudflare.com/workers/runtime-apis/nodejs/

I also tested with the latest version of wrangler, but the issue persists.

I believe this issue affects glen users targeting JavaScript runtimes without polyfills for node:fs.

Reproduction Steps

After installing Gleam and wrangler, run the following commands:

git clone https://github.com/Comamoca/share
cd share/gleam_glen_nodefs_error
gleam build
wrangler dev

The error occurs when running wrangler dev, and the development server fails to start.

If it works properly, the server starts and you can access the localhost URL shown in wrangler, which should display:

On a Cloudflare worker!

Cause Analysis

My personal guess is that when glen is compiled, it includes imports from Node.js built-in packages such as node:fs.

Below is an excerpt from the compiled glen code:

// glen.mjs
import { stream_file as do_file_stream, file_exists } from "./glen.ffi.node.mjs";
import * as $status from "./glen/status.mjs";
import * as $ws from "./glen/ws.mjs";
import { upgrade } from "./ws.ffi.mjs";

To resolve this, I think FFI and modules that use Node.js built-ins like fs should be separated from the core glen module, for example by moving file serving and streaming functions to a separate module like glen/node.

I am currently investigating solutions, but the functions using node:fs are currently mixed in, so I am unsure how to handle this.

https://github.com/MystPi/glen/blob/2a3f8709242dbfbe2fd7fcc93d975f291adc49f4/src/glen.gleam#L137-L141


If you need me to explain or help polish the English further or provide explanations for specific parts, let me know!

Comamoca avatar Aug 08 '25 23:08 Comamoca