Skip to content

Add a global Navigator object #39540

Description

@jimmywarting

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

  • geolocation
  • connection
  • hardwareConcurrency
  • platform
  • language
  • onLine
  • userAgentData
  • getBattery
  • getGamepads
  • vibrate
  • permissions
  • worker: implement Web Locks API #36502
  • usb
  • clipboard
  • storage + File System Access + estimates (whatwg/fs)
  • deviceMemory
  • presentation
  • bluetooth
  • userAgent

(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

Activity

  1. targos commented on Jul 27, 2021

    @targos
    Member

    I'm +1 on adding the navigator object, with APIs that make sense for Node.js.
    We could start with relatively easy ones lik. hardwareConcurrency or platform

  2. tniessen commented on Jul 31, 2021

    @tniessen
    Member

    Refs: #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 (neither true nor false is a meaningful value).
    • NavigatorPlugins: ouch
    • NavigatorConcurrentHardware: this is an indication at best and less useful than os.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, false can 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 errorCallback can 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 under ulimit, 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, false can 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 errorCallback can 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 navigator and 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.

  3. jimmywarting commented on Jul 31, 2021

    @jimmywarting
    Author

    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 secure
    • clipboard: just neat. Not so important... complex to get it right on windows, linux, mac, that's why it would be nice to have
    • storage + File System Access I 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/overview

    Geolocation: 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

  4. jasnell commented on Jul 31, 2021

    @jasnell
    Member

    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.

  5. tniessen commented on Jul 31, 2021

    @tniessen
    Member

    permissions: To request, revoke & query access to more powerful features and making NodeJS more secure

    I 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.

    storage

    I 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 Access

    The 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?

  6. jimmywarting commented on Jul 31, 2021

    @jimmywarting
    Author

    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's

    This 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')
  7. jimmywarting commented on Jul 31, 2021

    @jimmywarting
    Author

    Deno has a permission api on it's Deno namespace... https://deno.land/manual/runtime/permission_apis with some degree of cli prompts

  8. tniessen commented on Jul 31, 2021

    @tniessen
    Member

    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_process APIs and any native addons. (Similarly, in Deno, --allow-run and --allow-plugin essentially remove any security guarantees.)

  9. tniessen commented on Aug 4, 2021

    @tniessen
    Member

    I believe @addaleax or @jasnell did some work around permission-based security models for Node.js.

    Found it: #22112

  10. moved this to Pending triage in Node.js feature requestson Jan 16, 2022
  11. 7 remaining items

  12. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jan 8, 2023
  13. dnalborczyk commented on Jan 8, 2023

    @dnalborczyk
    Contributor

    example of current values for globalThis.navigator.userAgent:

    Cloudflare Workers: Cloudflare-Workers
    Deno: Deno/1.29.2
    Bun: Bun/0.4.0

  14. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jan 9, 2023
  15. muzuiget commented on Jun 2, 2023

    @muzuiget

    bun currently implements:

    Navigator {
      userAgent: "Bun/0.6.6",
      hardwareConcurrency: 4
    }
    
  16. jimmywarting commented on Jun 6, 2023

    @jimmywarting
    Author

    how 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

  17. tniessen commented on Oct 19, 2023

    @tniessen
    Member

    For anyone else who missed this (like I did), globalThis.navigator has 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...

  18. zm-cttae commented on Oct 19, 2023

    @zm-cttae

    Could someone kindly add navigator.platform so we can have a cross-platform OS targeting method?

  19. TheSainEyereg commented on Oct 19, 2023

    @TheSainEyereg

    Seems like this changes already broke some libraries e.g. pdf.js which now thinks that navigator has "platform" property

    IMG_20231019_180922_239.jpg

    IMG_20231019_180936_868.jpg

    In NodeJS 20.5.0 all works fine

  20. zm-cttae commented on Oct 19, 2023

    @zm-cttae

    Noting here also that Process.platform and Navigator.platform are different e.g. Navigator value is capitalised

  21. github-actions commented on Apr 17, 2024

    @github-actions
    Contributor

    There 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.

  22. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Apr 17, 2024
  23. github-actions commented on May 17, 2024

    @github-actions
    Contributor

    There 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.

  24. jakub-g commented on Jan 25, 2025

    @jakub-g
    Contributor

    Status quo: global.navigator shipped in in node@21

    https://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.hardwareConcurrency
    • navigator.language
    • navigator.languages
    • navigator.platform
    • navigator.userAgent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature requestIssues requesting new Node.js features.staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions