README.md

March 23, 2026 · View on GitHub

Bare

Small and modular JavaScript runtime for desktop and mobile. Like Node.js, it provides an asynchronous, event-driven architecture for writing applications in the lingua franca of modern software. Unlike Node.js, it makes embedding and cross-device support core use cases, aiming to run just as well on your phone as on your laptop. The result is a runtime ideal for networked, peer-to-peer applications that can run on a wide selection of hardware.

npm i -g bare

Usage

bare [flags] [filename] [...args]

Evaluate a script or start a REPL session if no script is provided.

Arguments:
  [filename]              Optional. The name of a script to evaluate
  [...args]               Additional arguments made available to the script

Flags:
  --version|-v            Print the Bare version
  --eval|-e <script>      Evaluate an inline script
  --print|-p <script>     Evaluate an inline script and print the result
  --inspect               Activate the inspector
  --inspect-port <port>   Configure the port on which the inspector will run (default: 9229)
  --expose-gc             Expose garbage collection APIs
  --help|-h               Show help

The specified <script> or <filename> is run using Module.load(). For more information on the module system and the supported formats, see https://github.com/holepunchto/bare-module.

Architecture

Bare is built on top of https://github.com/holepunchto/libjs, which provides low-level bindings to V8 in an engine independent manner, and https://github.com/libuv/libuv, which provides an asynchronous I/O event loop. Bare itself only adds a few missing pieces on top to support a wider ecosystem of modules:

  1. A module system supporting both CJS and ESM with bidirectional interoperability between the two.
  2. A native addon system supporting both statically and dynamically linked addons.
  3. Light-weight threads with synchronous joins and SharedArrayBuffer support.

Everything else if left to userland modules to implement using these primitives, keeping the runtime itself succinct and bare. By abstracting over both the underlying JavaScript engine using libjs and platform I/O operations using libuv, Bare allows module authors to implement native addons that can run on any JavaScript engine that implements the libjs ABI and any system that libuv supports.

API

Bare

The core JavaScript API of Bare is available through the global Bare namespace.

Bare.platform

The identifier of the operating system for which Bare was compiled. The possible values are android, darwin, ios, linux, and win32.

Bare.arch

The identifier of the processor architecture for which Bare was compiled. The possible values are arm, arm64, ia32, mips, mipsel, riscv64, and x64.

Bare.argv

The command line arguments passed to the process when launched.

Bare.pid

The ID of the current process.

Bare.exitCode

The code that will be returned once the process exits. If the process is exited using Bare.exit() without specifying a code, Bare.exitCode is used.

Bare.version

The Bare version string.

Bare.versions

An object containing the version strings of Bare and its dependencies.

Bare.exit([code])

Immediately terminate the process or current thread with an exit status of code which defaults to Bare.exitCode.

Bare.suspend([linger])

Suspend the process and all threads. This will emit a suspend event signalling that all work should stop immediately. When all work has stopped and the process would otherwise exit, an idle event will be emitted. If the process is not resumed from an idle event listener, the loop will block until the process is resumed.

Bare.wakeup([deadline])

Wake the process and all threads during suspension. This will emit a wakeup event signalling that work may be performed until deadline is reached.

Bare.idle()

Immediately suspend the event loop and trigger the idle event.

Bare.resume()

Resume the process and all threads after suspension. This can be used to cancel suspension after the suspend event has been emitted and up until all idle event listeners have run.

Bare.on('uncaughtException', err)

Emitted when a JavaScript exception is thrown within an execution context without being caught by any exception handlers within that execution context. By default, uncaught exceptions are printed to stderr and the processes aborted. Adding an event listener for the uncaughtException event overrides the default behavior.

Bare.on('unhandledRejection', reason, promise)

Emitted when a JavaScript promise is rejected within an execution context without that rejection being handled within that execution context. By default, unhandled rejections are printed to stderr and the process aborted. Adding an event listener for the unhandledRejection event overrides the default behavior.

Bare.on('beforeExit', code)

Emitted when the loop runs out of work and before the process or current thread exits. This provides a chance to schedule additional work and keep the process from exiting. If additional work is scheduled, beforeExit will be emitted again once the loop runs out of work.

If the process is exited explicitly, such as by calling Bare.exit() or as the result of an uncaught exception, the beforeExit event will not be emitted.

Bare.on('exit', code)

Emitted when the process or current thread exits. If the process is forcefully terminated from an exit event listener, the remaining listeners will not run.

Caution


Additional work MUST NOT be scheduled from an exit event listener.

Bare.on('suspend', linger)

Emitted when the process or current thread is suspended. Any in-progress or outstanding work, such as network activity or file system access, should be deferred, cancelled, or paused when the suspend event is emitted and no additional work should be scheduled. A suspend event listener may call Bare.resume() to cancel the suspension.

Bare.on('wakeup', deadline)

Emitted when the process or current thread wakes up during suspension. Once the process becomes idle, or if the process is not idle by the time deadline has passed, the process will suspend itself again and an idle event be emitted. A wakeup event listener may call Bare.resume() to resume the process.

Bare.on('idle')

Emitted when the process or current thread becomes idle after suspension. After all handlers have run, the event loop will block and no additional work be performed until the process is resumed. An idle event listener may call Bare.resume() to cancel the suspension.

Bare.on('resume')

Emitted when the process or current thread resumes after suspension. Deferred and paused work should be continued when the resume event is emitted and new work may again be scheduled.

Lifecycle

stateDiagram
  direction LR
  [*] --> Active
  Active --> Suspending: Bare.suspend()
  Active --> Terminated: Bare.exit()
  Active --> Exiting
  Suspending --> Active: Bare.resume()
  Suspending --> Awake: Bare.wakeup()
  Suspending --> Suspended: Bare.idle()
  Suspending --> Terminated: Bare.exit()
  Suspending --> Idle
  Awake --> Active: Bare.resume()
  Awake --> Suspended: Bare.idle()
  Awake --> Terminated: Bare.exit()
  Awake --> Idle
  Idle --> Suspended
  Idle --> Active: Bare.resume()
  Idle --> Terminated: Bare.exit()
  Suspended --> Active
  Suspended --> Awake: Bare.wakeup()
  Terminated --> Exiting
  Exiting --> [*]

Bare.Addon

The Bare.Addon namespace provides support for loading native addons, which are typically written in C/C++ and distributed as shared libraries.

Note


This is an advanced API that users should never have to interact with directly.

Addon.cache

The global cache of loaded addons.

Addon.host

The target triplet identifying the current addon host.

const url = Addon.resolve(specifier, parentURL[, options])

Resolve a native addon specifier by searching for a static native addon or dynamic object library matching specifier imported from parentURL.

Options are reserved.

const addon = Addon.load(url[, options])

Load a static or dynamic native addon identified by url. If url is not a static native addon, Bare will instead look for a matching dynamic object library.

Options are reserved.

addon.url

The WHATWG URL identifier of the addon.

addon.exports

The exports of the addon.

Bare.Thread

The Bare.Thread namespace provides support for lightweight threads. Threads are similar to workers in Node.js, but provide only minimal API surface for creating and joining threads.

Note


This is an advanced API that users should never have to interact with directly.

Thread.isMainThread

true if the current thread is the main thread.

Thread.self

A reference to the current thread as a ThreadProxy object. Will be null on the main thread.

Thread.self.data

The data that was passed to the current thread on creation. Will be null if no data was passed.

const thread = new Thread([filename][, options][, callback])

Start a new thread that will run the contents of filename. If callback is provided, its function body will be treated as the contents of filename and invoked on the new thread with Thread.self.data passed as an argument.

Options include:

{
  // Optional data to pass to the thread
  data: null,
  // Optional transfer list
  transfer: [],
  // Optional file source, will be read from `filename` if neither `source` nor `callback` are provided
  source: string | Buffer,
  // Optional source encoding if `source` is a string
  encoding: 'utf8',
  // Optional stack size in bytes, pass 0 for default
  stackSize: 0
}

const thread = Thread.create([filename][, options][, callback])

Convenience method for the new Thread() constructor

thread.joined

Whether or not the thread has been joined with the current thread.

thread.join()

Block and wait for the thread to exit.

thread.suspend([linger])

Suspend the thread. Equivalent to calling Bare.suspend() from within the thread.

thread.wakeup([deadline])

Wake the thread. Equivalent to calling Bare.wakeup() from within the thread.

thread.resume()

Resume the thread. Equivalent to calling Bare.resume() from within the thread.

thread.terminate()

Terminate the thread. Equivalent to calling Bare.exit() from within the thread.

Bare.IPC

The Bare.IPC namespace provides support for optional streaming communication between an embedder and JavaScript code. By default, its value is null indicating that streaming communication is not supported. If set by embedders, Bare.IPC is expected to be an instance of a https://github.com/holepunchto/bare-stream Duplex stream.

Note


This is an advanced API that users should never have to interact with directly.

Embedding

Bare can easily be embedded using the C API defined in include/bare.h:

#include <bare.h>
#include <uv.h>

bare_t *bare;
bare_setup(uv_default_loop(), platform, &env /* Optional */, argc, argv, options, &bare);

bare_load(bare, filename, source, &module /* Optional */);

bare_run(bare, UV_RUN_DEFAULT);

int exit_code;
bare_teardown(bare, UV_RUN_DEFAULT, &exit_code);

If source is NULL, the contents of filename will instead be read at runtime. For examples of how to embed Bare on mobile platforms, see https://github.com/holepunchto/bare-android and https://github.com/holepunchto/bare-ios.

Suspension

Bare provides a mechanism for implementing process suspension, which is needed for platforms with strict application lifecycle constraints, such as mobile platforms. When suspended, using either bare_suspend() from C or Bare.suspend() from JavaScript, a suspend event will be emitted on the Bare namespace. Then, when the loop has no work left and would otherwise exit, an idle event will be emitted and the loop blocked, keeping it from exiting. When the process is later resumed, using either bare_resume() from C or Bare.resume() from JavaScript, a resume event will be emitted and the loop unblocked, allowing it to exit when no work is left.

While suspended, the loop may also be woken up for limited periods of time to perform work, using either bare_wakeup() from C or Bare.wakeup() from JavaScript, which will emit a wakeup event. Each wakeup has an associated deadline after which the loop will be stopped and the process suspended again, emitting another idle event.

Building

https://github.com/holepunchto/bare-make is used for compiling Bare. Start by installing the tool globally:

npm i -g bare-make

Next, install the required build and runtime dependencies:

npm i

Then, generate the build system:

bare-make generate

This only has to be run once per repository checkout. When updating bare-make or your compiler toolchain it might also be necessary to regenerate the build system. To do so, run the command again with the --no-cache flag set to disregard the existing build system cache:

bare-make generate --no-cache

With a build system generated, Bare can be compiled:

bare-make build

When completed, the bare(.exe) binary will be available in the build/bin directory and the libbare.(a|lib) and (lib)bare.(dylib|dll|lib) libraries will be available in the root of the build directory.

Linking

When linking against the static libbare.(a|lib) library, make sure to use whole archive linking as Bare relies on constructor functions for registering native addons. Without whole archive linking, the linker will remove the constructor functions as they aren't referenced by anything.

Options

Bare provides a few compile options that can be configured to customize various aspects of the runtime. Compile options may be set by passing the --define option=value flag to the bare-make generate command when generating the build system.

Warning


The compile options are not covered by semantic versioning and are subject to change without warning.

OptionDefaultDescription
BARE_ENGINEgithub:holepunchto/libjsThe JavaScript engine to use
BARE_PREBUILDSONEnable prebuilds for supported third-party dependencies
BARE_MEMORY_LIMIT0The default memory limit of each JavaScript heap

Platform support

Bare uses a tiered support system to manage expectations for the platforms that it targets. Targets may move between tiers between minor releases and as such a change in tier will not be considered a breaking change.

Tier 1: Platform targets for which prebuilds are provided as defined by the .github/workflows/prebuild.yml workflow. Compilation and test failures for these targets will cause workflow runs to go red.

Tier 2: Platform targets for which Bare is known to work, but without automated compilation and testing. Regressions may occur between releases and will be considered bugs.

Note


Development happens primarily on Apple hardware with Linux and Windows systems running as virtual machines.

PlatformArchitectureVersionTierNotes
Linuxarm64>= Linux 5.15, >= GNU C Library 2.351Ubuntu 22.04, Debian 12, OpenWrt 23.05
Linuxx64>= Linux 5.15, >= GNU C Library 2.351Ubuntu 22.04, Debian 12, OpenWrt 23.05
Linuxriscv64>= Linux 6.8, >= GNU C Library 2.392Ubuntu 24.04, Debian 13
Linuxarm>= Linux 5.10, >= musl 1.22Alpine 3.13, OpenWrt 22.03
Linuxarm64>= Linux 5.10, >= musl 1.22Alpine 3.13, OpenWrt 22.03
Linuxia32>= Linux 5.10, >= musl 1.22Alpine 3.13, OpenWrt 22.03
Linuxx64>= Linux 5.10, >= musl 1.22Alpine 3.13, OpenWrt 22.03
Linuxriscv64>= Linux 6.6, >= musl 1.22Alpine 3.20
Linuxmips>= Linux 5.10, >= musl 1.22OpenWrt 22.03
Linuxmipsel>= Linux 5.10, >= musl 1.22OpenWrt 22.03
Androidarm>= 101
Androidarm64>= 101
Androidia32>= 101
Androidx64>= 101
macOSarm64>= 12.01
macOSx64>= 12.01
iOSarm64>= 14.01
iOSx64>= 14.01Simulator only
Windowsarm64>= Windows 111
Windowsx64>= Windows 101

Modules

Bare provides no standard library beyond the core JavaScript API available through the Bare namespace. Instead, we maintain a comprehensive collection of external modules built specifically for Bare.

ModuleDescriptionVersion
bare-abortCause abnormal program termination and generate a crash report
bare-ansi-escapesParse and produce ANSI escape sequences
bare-assertAssertion library for JavaScript
bare-atomicsNative synchronization primitives for JavaScript
bare-bufferNative buffers for JavaScript
bare-bundleApplication bundle format for JavaScript, inspired by https://github.com/electron/asar
bare-channelInter-thread messaging for JavaScript
bare-consoleWHATWG debugging console for JavaScript
bare-cryptoCryptographic primitives for JavaScript
bare-daemonCreate and manage daemon processes in JavaScript
bare-dgramNative UDP for JavaScript
bare-dnsDomain name resolution for JavaScript
bare-encodingWHATWG text encoding interfaces for JavaScript
bare-envEnvironment variable support for JavaScript
bare-eventsEvent emitters for JavaScript
bare-fetchWHATWG Fetch implementation for Bare
bare-form-dataForm data support for Bare
bare-formatString formatting for JavaScript
bare-fsNative file system for JavaScript
bare-hrtimeHigh-resolution timers for JavaScript
bare-http1HTTP/1 library for JavaScript
bare-httpsHTTPS library for JavaScript
bare-inspectInspect objects as strings for debugging
bare-inspectorV8 inspector support for Bare
bare-ipcLightweight pipe-based IPC for Bare
bare-loggerLow-level logger for Bare with system log integration
bare-moduleModule support for JavaScript
bare-osOperating system utilities for JavaScript
bare-packBundle packing for Bare
bare-pathPath manipulation library for JavaScript
bare-performancePerformance monitoring for Bare
bare-pipeNative I/O pipes for JavaScript
bare-queue-microtaskMicrotask queuing for Bare
bare-readlineLine editing for interactive CLIs with command history
bare-realmRealm support for Bare
bare-replRead-Evaluate-Print-Loop environment for JavaScript
bare-rpchttps://github.com/holepunchto/librpc ABI compatible RPC for Bare
bare-semverMinimal semantic versioning library for Bare
bare-signalsNative signal handling for JavaScript
bare-storageMinimal, cross‑platform directory locator for Bare
bare-streamStreaming data for JavaScript
bare-structured-cloneStructured cloning algorithm for JavaScript
bare-subprocessNative process spawning for JavaScript
bare-tapMinimal TAP library for Bare
bare-tcpNative TCP sockets for JavaScript
bare-threadThread support for Bare
bare-timersNative timers for JavaScript
bare-tlsTransport Layer Security (TLS) streams for JavaScript
bare-ttyNative TTY streams for JavaScript
bare-typeCross-realm type predicates for Bare
bare-unpackBundle unpacking for Bare
bare-urlWHATWG URL implementation for JavaScript
bare-workerHigher-level worker threads for JavaScript
bare-wsWebSocket library for JavaScript
bare-zlibStream-based zlib bindings for JavaScript
bare-zmqLow-level ZeroMQ bindings for JavaScript

License

Apache-2.0