Skip to content

Proposal: Restore node-serve with npm-published native wrapper packages #11440

@mjackson

Description

@mjackson

Background

PR #11439 removed @remix-run/node-serve and the remix/node-serve export from the current beta so remix@next no longer pulls in the uWebSockets.js GitHub dependency that blocked pnpm and Deno installs. This is intended to be temporary.

We should restore node-serve in a future beta once its native dependency path is npm-only and package-manager friendly.

Proposal

Restore the package using a Remix-owned facade for uWebSockets.js plus thin native packages split by OS/architecture. The dependency graph should look like this:

remix
  -> @remix-run/node-serve
    -> @remix-run/uwebsockets-js
      -> optional platform package

@remix-run/node-serve should import the facade instead of upstream directly:

import * as uWS from '@remix-run/uwebsockets-js'

@remix-run/uwebsockets-js should be a small wrapper/facade package with no native binaries in its own tarball. It should expose the upstream API shape, ship ESM and CJS entry points, include the upstream types, and select the installed platform package at runtime.

Example optional dependency shape:

{
  "name": "@remix-run/uwebsockets-js",
  "optionalDependencies": {
    "@remix-run/uwebsockets-js-darwin-arm64": "20.66.0",
    "@remix-run/uwebsockets-js-darwin-x64": "20.66.0",
    "@remix-run/uwebsockets-js-linux-arm64-gnu": "20.66.0",
    "@remix-run/uwebsockets-js-linux-x64-gnu": "20.66.0",
    "@remix-run/uwebsockets-js-win32-x64": "20.66.0"
  }
}

Each platform package should be a thin npm-published copy of the upstream payload for exactly one OS/arch combination. It should contain the relevant native binaries, the JS wrapper files needed to load them, upstream type definitions, upstream license text, and source attribution.

Example platform package metadata:

{
  "name": "@remix-run/uwebsockets-js-linux-x64-gnu",
  "version": "20.66.0",
  "license": "Apache-2.0",
  "main": "./uws.js",
  "types": "./index.d.ts",
  "os": ["linux"],
  "cpu": ["x64"],
  "libc": ["glibc"]
}

Implementation Plan

  1. Restore packages/node-serve from the removal in PR Remove node-serve from next beta #11439.
  2. Add @remix-run/uwebsockets-js as the facade package and update node-serve to import it instead of uWebSockets.js directly.
  3. Add platform-specific packages for the native payload, one package per supported OS/arch combination.
  4. Add a reproducible sync script that vendors from a pinned upstream uWebSockets.js commit or tag and records source attribution for each package.
  5. Preserve upstream Apache-2.0 license text and source attribution in the facade/platform packages.
  6. Ensure the platform packages do not become regular hard dependencies of remix. If they live under packages/, update scripts/generate-remix.ts with an explicit internal/optional-native package skip mechanism so they are not auto-added to the umbrella package dependencies or exports.
  7. Make the facade throw a clear runtime error when optional dependencies were disabled, the current platform is unsupported, or the current Node ABI has no matching native binary.
  8. Restore the remix/node-serve export and add release notes once normal installs work through npm-only dependencies.

Acceptance Criteria

  • npm i remix@next, pnpm add remix@next, and deno add npm:remix@next do not require GitHub or other non-npm transitive dependencies.
  • Users normally do not need to manually install platform-specific packages.
  • The installed native payload is scoped to the user’s current OS/arch instead of shipping every platform in the default dependency tarball.
  • remix/node-serve works for supported platforms and fails with actionable messaging for unsupported or optional-dependency-disabled installs.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions