Repository navigation
Add a global Navigator object #39540
Description
Activity
- addedfeature requestIssues requesting new Node.js features.Issues requesting new Node.js features.
on Jul 27, 2021 I'm +1 on adding the navigator object, with APIs that make sense for Node.js.
We could start with relatively easy ones lik.hardwareConcurrencyorplatformReacted by Jacob HummerRefs: #39581 (comment)
The Navigator object is interesting because it brings together many APIs that can be useful, even in the context of Node.js
Navigator is defined by the HTML standard, not by the ECMAScript standard, and I am afraid most of its features are not necessarily meaningful in Node.js.
Navigator fields according to the current HTML standard:
NavigatorID: these values must be provided by each Node.js application and cannot be provided by Node.js itself. Some properties (e.g.,userAgent) do not really make sense outside of web browsers as far as I can tell.NavigatorLanguage: we could maybe use the system language here, but that is not necessarily the "user's preferred language." The user accessing the application might not be the same user that is running the Node.js process.NavigatorOnLine: this does not seem to make sense for Node.js applications that might be connected to multiple networks through multiple network interfaces.NavigatorContentUtils: this does not seem useful in Node.js.NavigatorCookies: this does not seem to make sense in Node.js (neithertruenorfalseis a meaningful value).NavigatorPlugins: ouchNavigatorConcurrentHardware: this is an indication at best and less useful thanos.cpus().
Suggested extensions:
NavigatorDeviceMemory: this does not seem helpful, and the use cases covered by the "Introduction" section in the draft do not apply to Node.js. More precise APIs exist in Node.js.NavigatorNetworkInformation: this seems to be pretty much useless for any server-side application because it is impossible for Node.js to tell what network interface the information should be referring to.USB: this might actually maybe be a useful feature.Geolocation: not sure if useful or how to implement this on a server.
Refs: #39581 (comment)
Navigator is defined by the HTML standard, not by the ECMAScript standard
I know.
NavigatorContentUtils: this does not seem useful in Node.js.
NavigatorCookies: this does not seem to make sense in Node.js (neither true nor false is a meaningful value).
NavigatorPlugins: ouch
NavigatorID: these values must be provided by each Node.js application and cannot be provided by Node.js itself. Some properties (e.g., userAgent) do not really make sense outside of web browsers as far as I can tell.
NavigatorLanguage: we could maybe use the system language here, but that is not necessarily the "user's preferred language." The user accessing the application might not be the same user that is running the Node.js process.Yes, I agree, and they are the ones I mean when I say they should not be implemented.
NavigatorDeviceMemory: this does not seem helpful, and the use cases covered by the "Introduction" section in the draft do not apply to Node.js. More precise APIs exist in Node.js.
Personally I find it interesting to have the RAM rounded to the nearest power of 2. But not having a lower bound of 0.25 and upper bound of 8 GiB as proposed in the specification.
And I don't think this information is imprecise. In my opinion it is not uncommon to need this rounded device memory.NavigatorOnLine: this does not seem to make sense for Node.js applications that might be connected to multiple networks through multiple network interfaces.
Even though a Node.js application can be connected to multiple networks through multiple network interfaces,
falsecan be returned if the application is completely disconnected.Geolocation: not sure if useful or how to implement this on a server.
If the machine does not have GPS, the
errorCallbackcan be called with the error https://www.w3.org/TR/geolocation/#dom-geolocationpositionerror-position_unavailable. It's true that it's hard to find a usecase for this one, but I think there's probably a useful purpose for this, for example a program that returns the current GPS location.We can, not implement APIs that are not useful in Node.js, while having Navigator and some useful APIs.
I also think we should discuss this in the issue, and possibly get the author's opinion, right?
Personally I find it interesting to have the RAM rounded to the nearest power of 2. But not having a lower bound of 0.25 and upper bound of 8 GiB as proposed in the specification.
And I don't think this information is imprecise. In my opinion it is not uncommon to need this rounded device memory.I am curious what a potential use case for this could be in Node.js. The use cases for browsers are outlined in the introductory section of the specification. But what about Node.js?
If I run one process on a machine with 256 MiB main memory (
deviceMemory === 0.25) it surely has more resources available than each process when running a thousand processes on a machine with 128 GiB memory (deviceMemory === 128). Unless I put the single process underulimit, in which case the device memory is even less meaningful.(Also, the primary aspect of the spec appears to be the header field that is sent by the browser: This document defines a HTTP Client Hint header to surface device capability for memory i.e. device RAM, in order to enable web apps to customize content depending on device memory constraints.)
NavigatorOnLine: this does not seem to make sense for Node.js applications that might be connected to multiple networks through multiple network interfaces.
Even though a Node.js application can be connected to multiple networks through multiple network interfaces,
falsecan be returned if the application is completely disconnected.Interesting. So as long as the server has any network interfaces that aren't down (e.g., a virtual network switch connecting Docker containers on the same machine with no external networking capabilities), this property would be
true? What use does this property have then?Geolocation: not sure if useful or how to implement this on a server.
If the machine does not have GPS, the
errorCallbackcan be called with the error https://www.w3.org/TR/geolocation/#dom-geolocationpositionerror-position_unavailable. It's true that it's hard to find a usecase for this one, but I think there's probably a useful purpose for this, for example a program that returns the current GPS location.I think the more interesting question is: what if there are two GPS sensors, each returning different locations? That being said, some operating systems do provide geolocations even without GPS hardware, so we could implement this as "if provided by the operating system in an unambiguous manner, we'll just accept it, and if it isn't, we don't support it."
We can, not implement APIs that are not useful in Node.js, while having Navigator and some useful APIs.
We surely can add
navigatorand implement only APIs that make sense in the context of Node.js. However, I am afraid that it could become a slippery slope toward incorrect or meaningless additions. These APIs were, for the most part, not designed for environments other than web browsers.The biggest reasons why i want to have a Navigator object is:
permissions: To request, revoke & query access to more powerful features and making NodeJS more secureclipboard: just neat. Not so important... complex to get it right on windows, linux, mac, that's why it would be nice to havestorage+File System AccessI quite like the File System Access. Being able to write cross platform code that utilize the file system in the same way is grate
I also worked with
navigator.bluetooth(forgot to put it up on the list) and wanted to have it in nodejs before.I think the more interesting question is: what if there are two GPS sensors, each returning different locations? That being said, some operating systems do provide geolocations even without GPS hardware, so we could implement this as "if provided by the operating system in an unambiguous manner, we'll just accept it, and if it isn't, we don't support it."
I kind of investigated how Google dose geolocation without gps using ip and wifi access points / mac addresses at some point and thought about impl it as a npm module at some point in my life
https://developers.google.com/maps/documentation/geolocation/overviewGeolocation: not sure if useful or how to implement this on a server.
There are ppl building Drones with NodeJS. NodeJS is more than just a server 😉
...Language would be useful with localization and Intl
There are ppl building Drones with NodeJS. NodeJS is more than just a server
Yes, and that's good but by itself is not enough to justify adding to core. The parts of the web platform API that we have adopted so far are bits that a) already overlap with existing core functions or b) are generally usable in all use cases, server or otherwise. Much of the navigator api is very specific to individual types of use cases that do not necessarily meet both of those criteria. I don't think anyone here is saying no outright, that would be silly, but we do need to be selective and deliberate.
Reacted by Tobias Nießen, Anna Henningsen, Matteo Collina and Stevenpermissions: To request, revoke & query access to more powerful features and making NodeJS more secureI believe @addaleax or @jasnell did some work around permission-based security models for Node.js. One of the main problems is that any permission system would make it entirely impossible to use native addons in Node.js because we cannot reasonably restrict their permissions. Also, how would we determine if a permission was granted or not? We surely cannot implement
"prompt", and we cannot rely on the file system, so the only option might be command-line arguments (similar to how deno does it) or environment variables. In my experience, it is much easier and more reliable to use operating system features, e.g., file permissions and iptables, to control access for server processes.storageI don't think Node.js implements any of the "storage endpoints" that would be affected by
navigator.storage, but this is the first time I am looking at it, so I might be misunderstanding the purpose of the API.File System AccessThe draft does seem to require these three functions to have any use:
window.showOpenFilePicker window.showSaveFilePicker window.showDirectoryPicker
I don't see how any of these could be implemented in Node.js.
There are ppl building Drones with NodeJS. NodeJS is more than just a server
Regardless of whether it is a good idea to build flying objects based on software that relies on dynamic memory allocations and crashes when it runs out of memory and that is incredibly difficult to statically analyze, I am not saying that there are no applications that won't benefit from geolocation. But are those few applications worth adding geolocation to Node.js core?
The draft does seem to require these three functions to have any use: showOpenFilePicker, showSaveFilePicker, showDirectoryPicker
Not really, you could take advantage of the sandboxed filesystem and use it without dialogs.
I know Deno was looking into adapting File system to co-exist with other api'sThis API would live in parallel with the existing low-level file system API provided by
Deno.open,Deno.write,Deno.read,Deno.readDir, ...Writing to a file:
import fs from 'node:fs' const fileHandle = await fs.getFileHandle("/tmp/foo.txt"); // Returns FileSystemFileHandle const writable = await fileHandle.createWritable(); const writer = writable.getWriter(); await writer.write(new TextEncoder().encode("Hello World")); await writer.close();
Also directory listing
const directoryHandle = await fs.getDirectoryHandle("/etc"); // Returns FileSystemDirectoryHandle for await (let [name, handle] of directoryHandle) { // ... }
https://wicg.github.io/file-system-access/
Or maybe we have a directoryHandle corresponding to the cwd or a complete secure sandboxed directory
const fileHandle = await navigator.storage.getDirectory();
I know there have been talks about getting a blob backed up by the file system and i hope it will land so we can upload large file with FormData, creating objectURLs for worker threads and transfering files with very little cost. This would be the most "correct" way to obtain a File from the filesystem.
With my File System Adapter I created a way to obtain a a Handle by doing something like
const handle = await getOriginPrivateDirectory(nodeAdapter, './public')
Deno has a permission api on it's Deno namespace... https://deno.land/manual/runtime/permission_apis with some degree of cli prompts
I know Deno was looking into adapting File system to co-exist with other api's
import fs from 'node:fs' const fileHandle = await fs.getFileHandle("/tmp/foo.txt"); // Returns FileSystemFileHandle
Oh sure, we can always do that, but then the code isn't really runtime-agnostic because it requires APIs specific to a certain runtime to retrieve file handles.
Deno has a permission api on it's Deno namespace
We could implement something like that, but, when enabled, it would make it impossible for applications to use the
child_processAPIs and any native addons. (Similarly, in Deno,--allow-runand--allow-pluginessentially remove any security guarantees.)7 remaining items
- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jan 8, 2023 example of current values for
globalThis.navigator.userAgent:Cloudflare Workers:
Cloudflare-Workers
Deno:Deno/1.29.2
Bun:Bun/0.4.0- removedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Jan 9, 2023 bun currently implements:
Navigator { userAgent: "Bun/0.6.6", hardwareConcurrency: 4 }Reacted by Niels Swimberghehow do you feel about
navigator.userAgentData?
Note that it's an experimental technology. and behind a unofficial draft spec.https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Sec-CH-UA
For anyone else who missed this (like I did),
globalThis.navigatorhas been added in #47769. There are already multiple PRs attempting to add properties that, in my opinion, do not benefit Node.js, so here we go...Reacted by fregante and jakub-gCould someone kindly add
navigator.platformso we can have a cross-platform OS targeting method?Noting here also that
Process.platformandNavigator.platformare different e.g. Navigator value is capitalisedgithub-actions commented
on Apr 17, 2024 on Apr 17, 2024 – with GitHub ActionsContributorMore actionsThere has been no activity on this feature request for 5 months. To help maintain relevant open issues, please add the never-stale
Issues and PRs exempt from automated stale handling. label or close this issue if it should be closed. If not, the issue will be automatically closed 6 months after the last non-automated comment.
For more information on how the project manages feature requests, please consult the feature request management document.- addedstaleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.Issues and PRs marked stale due to inactivity and scheduled for automatic closure.
on Apr 17, 2024 github-actions commented
on May 17, 2024 on May 17, 2024 – with GitHub ActionsContributorMore actionsThere has been no activity on this feature request and it is being closed. If you feel closing this issue is not the right thing to do, please leave a comment.
For more information on how the project manages feature requests, please consult the feature request management document.
Status quo:
global.navigatorshipped in in node@21https://nodejs.org/docs/latest-v22.x/api/globals.html#navigator_1
APIs implemented as of node@22 (shipped between 21.0.0 and 21.2.0):
navigator.hardwareConcurrencynavigator.languagenavigator.languagesnavigator.platformnavigator.userAgent
Reacted by David P.


I think there is a bunch of interesting web related things on the navigator object itself that could fit into NodeJS and dose not require a UI.
Deno, Bun.js, Browser and all Worker threads has it. NodeJS is the only platform that lacks it
Things i find interesting to also have in a NodeJS environment is
(not saying we should go ahead and implement all of this)
I think there should at least exist a global navigator object so ppl can at least polyfill missing features onto the global navigator