os.platform()

Returns the operating system platform string the Node.js binary was compiled for.

Signature
os.platform()
  • Added in Node.js v0.5.0

Return value

stringA string identifying the operating system platform the Node.js binary was compiled for. Possible values are 'aix', 'darwin', 'freebsd', 'linux', 'openbsd', 'sunos' and 'win32'. ('android' may also be returned; Android support is experimental.)

os.platform() returns the platform the running Node binary was compiled for. The value is fixed at compile time, so it never changes during a process and is identical to process.platform — the two are interchangeable, and process.platform needs no import.

When to reach for it

Any branch where the operating system genuinely changes behaviour: choosing a shell command, picking a config directory, deciding whether to append .exe, or selecting the right line ending. It is the switch value for those cases.

What trips people up

Three names surprise people. macOS is 'darwin', not 'macos' or 'osx'. Windows is 'win32' on 64-bit systems too — it is the API family, not the word size, so === 'win64' is a bug that silently never matches. And Linux is 'linux' with no distro information at all; there is no way to tell Alpine from Ubuntu here.

Prefer testing for a capability over branching on the name where you can: use os.EOL instead of comparing platforms for line endings, path.sep and path.join() instead of hand-building separators, and os.homedir() instead of choosing between $HOME and %USERPROFILE% yourself.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Pick a per-OS config directory for an application's settings file
  • Append .exe to a binary name only on Windows
  • Skip a POSIX-only test or feature when running on Windows

Frequently asked questions

How do I check if Node.js is running on Windows?

Compare os.platform() (or process.platform) to the string 'win32'. That value is returned on 64-bit Windows too, because it names the Win32 API family rather than the word size, so testing for 'win64' or 'windows' will never match.

What does os.platform() return on macOS?

It returns 'darwin', after the kernel macOS is built on — never 'macos', 'osx' or 'mac'. Use os.platform() === 'darwin' for the check, and a lookup table if you need to show a friendly name to a user.

Is os.platform() the same as process.platform?

Yes, they return the identical string, both fixed when the Node binary was compiled. process.platform needs no require, so it is marginally more convenient; use os.platform() when you are already importing os for other things.

More examples

Choose a per-OS config directory

The printed path follows each platform's convention rather than dumping a dotfile in the home directory everywhere. Note the default branch catches linux, freebsd and the rest, which is why a switch beats a chain of equality checks here.

Example · javascript
const os = require('node:os');
const path = require('node:path');

function configDir(appName) {
  const home = os.homedir();
  switch (os.platform()) {
    case 'win32':
      return path.join(process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming'), appName);
    case 'darwin':
      return path.join(home, 'Library', 'Application Support', appName);
    default:
      return path.join(process.env.XDG_CONFIG_HOME ?? path.join(home, '.config'), appName);
  }
}

console.log('platform:', os.platform());
console.log('config dir:', configDir('demo-app'));
console.log('under home:', configDir('demo-app').startsWith(os.homedir()) || os.platform() === 'win32');

Normalise the platform into a friendly name

Users never recognise 'darwin' or 'win32' in a support form, so a lookup table turns the raw value into something readable while falling back to the raw string for anything unmapped. os.release() adds the kernel version, which is the other half of a useful environment report.

Example · javascript
const os = require('node:os');

const NAMES = {
  darwin: 'macOS',
  win32: 'Windows',
  linux: 'Linux',
  freebsd: 'FreeBSD',
  openbsd: 'OpenBSD',
  sunos: 'SunOS',
  aix: 'AIX'
};

const p = os.platform();
console.log('raw:', p);
console.log('display name:', NAMES[p] ?? p);
console.log('release:', os.release());
console.log('known platform:', p in NAMES);

Prefer capability checks to platform checks

Both approaches agree here, which is exactly why the manual version survives review and then breaks somewhere unusual. os.EOL and path.sep are derived from the same platform value but stay correct without you enumerating cases, so reach for them instead of a comparison.

Example · javascript
const os = require('node:os');
const path = require('node:path');

// Brittle: hand-rolled per-platform values.
const manualEol = os.platform() === 'win32' ? '\r\n' : '\n';
const manualSep = os.platform() === 'win32' ? '\\' : '/';

// Robust: let Node tell you.
console.log('eol matches:', manualEol === os.EOL);
console.log('sep matches:', manualSep === path.sep);
console.log('joined path:', path.join('data', 'cache', 'index.json'));
console.log('delimiter:', JSON.stringify(path.delimiter));

Discussion

  • Be the first to comment on this lesson.