201

I'm writing an application using Node.js.

One of the functions I want to create is to open the default web browser and navigate to a specific URL.

I want it to be portable so that it runs on Windows/Mac/Linux.

Alex
  • 6,849
  • 6
  • 19
  • 36
Qing Xu
  • 2,704
  • 2
  • 22
  • 21

10 Answers10

257

Use open (formerly known as opn) because it will handle the cross platform issue. To install:

$ npm install open

To use:

const open = require('open');

// opens the url in the default browser 
open('http://sindresorhus.com');
 
// specify the app to open in 
open('http://sindresorhus.com', {app: 'firefox'});
Josh Kelley
  • 56,064
  • 19
  • 146
  • 246
ForbesLindesay
  • 10,482
  • 3
  • 47
  • 74
  • ForbesLindesay the callback is being called immediately, instead of when the window is closed. Any ideas? – Sam Selikoff Mar 01 '14 at 18:30
  • 3
    Not sure, might be worth giving https://github.com/domenic/opener a try as an alternative module with the same API. It looks like it has a proper issue tracker you could open an issue on. It may just be an oddity of how browsers report the process as ending though, so it may not be easily fixable. – ForbesLindesay Mar 02 '14 at 01:11
  • 2
    It looks like opener works on Mac / Windows / Linux whereas open only works on Mac / Windows so opener is preferable. – Tom Nov 05 '15 at 19:21
  • This works for me, but it appears the child process is not detached, so when the server goes down, so does my firefox! Not sure how to get "open" to detach the child process... any idea? – sidewinderguy Mar 25 '16 at 01:49
  • To answer my own question (maybe) it looks like the "opener" package has an "unref()" call that lets you detach. So maybe that's another reason to use "opener" instead of "open" package. Not sure though. – sidewinderguy Mar 25 '16 at 01:52
  • Well, I tried "opener" with "unref()" and it doesn't work for me (on linux). Not sure what to do. Seems like everyone would want the browser process to stay open, even if node dies, right? – sidewinderguy Mar 25 '16 at 01:57
  • Well, the problem with this is that when I use nodemon and changes get automatically refreshed, opn() opens another window. So every time you save, new window in browser opens up. – Marko Jul 08 '17 at 12:37
  • Now how do I get data back from this browser, for example as part of an SSO flow? – Ozymandias Apr 16 '21 at 23:48
  • @AjaxLeung you'd usually do this via some other channel. e.g. for SSO you can generate a secure random token, include it in the OAuth request, and have a server store the auth result along with that token, then your CLI can use that token to request the result. – ForbesLindesay May 02 '21 at 19:22
  • FWIW, `open` seems to support Linux now. – JakeRobb Aug 31 '21 at 14:25
92
var url = 'http://localhost';
var start = (process.platform == 'darwin'? 'open': process.platform == 'win32'? 'start': 'xdg-open');
require('child_process').exec(start + ' ' + url);
lexa-b
  • 1,759
  • 15
  • 15
12

node-open is deprecated. Now use open:

const open = require('open')

await open('http://sindresorhus.com') // Opens the url in the default browser

await open('http://sindresorhus.com', {app: 'firefox'}) // Specify the app to open in
JakeRobb
  • 1,711
  • 1
  • 17
  • 32
Olivier C
  • 899
  • 1
  • 13
  • 14
7

Install:

$ npm install open

Usage:

const open = require('open');
 
(async () => {
    // Opens the image in the default image viewer and waits for the opened app to quit.
    await open('unicorn.png', {wait: true});
    console.log('The image viewer app quit');
 
    // Opens the URL in the default browser.
    await open('https://sindresorhus.com');
 
    // Opens the URL in a specified browser.
    await open('https://sindresorhus.com', {app: 'firefox'});
 
    // Specify app arguments.
    await open('https://sindresorhus.com', {app: ['google chrome', '--incognito']});
})();
pino
  • 71
  • 1
  • 1
  • 2
    Hi there, thank you for sharing this answer. A link to the documentation on async/await would be nice to add just for reference. Nice comments in the code though :) – William Patton Nov 24 '20 at 21:58
6

Windows + Express

app.listen(3000, ()=>{
    require('child_process').exec('start http://localhost:3000/');
});
Vadim
  • 306
  • 1
  • 5
  • 13
6

You may need to implement a switch using the value of ...

require('os').type()

And then use spawn("open") or spawn("xdg-open") depending on the platform?

J. Scott Elblein
  • 4,013
  • 15
  • 58
  • 94
Soren
  • 14,402
  • 4
  • 41
  • 67
  • 4
    In windows, i try spawn("explorer.exe",['http://www.stackoverflow.com']), the windows explorer will select the default browser to open the URL. – Qing Xu Dec 14 '11 at 13:56
  • 2
    @QingXu awesome! `require('child_process').spawn('explorer', ['url'])` is a nice oneliner! – TWiStErRob Feb 21 '16 at 23:46
3

Simply Use

require('child_process').exec('start https://www.google.co.in/');

It's Worked For me.

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
2

The easiest and neatest way, IMHO is using an npm package called openurl. Do a npm install openurl . You could try this real quick in your Nodejs REPL

require("openurl").open("http://stackoverflow.com/questions/8500326/how-to-use-nodejs-to-open-default-browser-and-navigate-to-a-specific-url")

You could also send emails with it if the need arises like so; require("openurl").open("mailto:janedoe@example.com")

EL Taipan
  • 51
  • 7
1
#!/usr/bin/env node

const url = 'http://localhost'
require('child_process')
  .exec((process.platform
         .replace('darwin','')
         .replace(/win32|linux/,'xdg-') + 'open ' + url));
  • 1
    Please consider adding a brief explanation of [how and why this solves the problem](https://meta.stackoverflow.com/q/392712/13138364). This will help readers to better understand your solution. – tdy Nov 24 '21 at 05:20
  • Code only answers are frowned upon on SO and are often downvoted. Context and explanation are usually necessary for understanding the given solution, and to distinguish when your solution should/should not be applied. Answers with explanations are more helpful to future visitors, thus upvoted much more often. SO is designed to be a place to *learn* how to fix issues. It is also good to indicate the context for which a particular answer applies, such as OS platform, or specific edge cases. Links to documentation or further info are also encouraged (but the actual solution must also be embeded.) – SherylHohman Dec 01 '21 at 17:17
0
var url = '\\index.html';
var start = (process.platform == 'darwin'? 'open': process.platform == 'win32'? 'start': 'xdg-open');
require('child_process').exec(start + ' ' + __dirname + url);

Lexa-B’s answer worked best for me, but I was getting “Windows could not locate index.html” error. I was using lexa-b code child_process exec command to open a local webpage within an npm package I was writing. Needed to open an html file in my npm package when running it / opening it from package bin.js with npx command.

All that was needed was to append __dirname to file path to ensure the relative directory path to the file calling the child_process was correct. The child_process was running at the home folder, which is far away from the npx temp file location. __dirname solves that problem and links the two, solving my missing file error.

C. Alex
  • 44
  • 3