Skip to main content

Creating Standalone Executables

QuickJS-ng provides two methods for creating standalone executables from JavaScript code:
  1. Using qjs -c - Simple, single-file bundling (recommended)
  2. Using qjsc -e - Full C compilation with custom modules
The simplest way to create a standalone executable is using the qjs interpreter’s compile flag.

Basic Usage

This creates a standalone executable named app that bundles your JavaScript file with the QuickJS runtime.

How It Works

1

Compile to Bytecode

The JavaScript file is compiled to QuickJS bytecode
2

Append to Executable

The bytecode is appended to a copy of the qjs executable with a trailer to help locate it
3

Create Executable

The result is a self-contained executable with the same runtime dependencies as qjs

Complete Example

Using a Different Base Executable

By default, qjs -c uses the current qjs executable as the base. You can specify a different one:
The --exe parameter expects an absolute path, such as ~/bin/qjs or $HOME/bin/qjs.
This is useful for:
  • Cross-compilation for different platforms
  • Using a custom-built qjs with specific features
  • Creating executables with different runtime configurations

Limitations

No JavaScript bundling is performed. The specified JS file cannot depend on other files via import or require.
To work around this limitation, use a bundler:

Bundling Multiple Files

Since qjs -c only compiles a single file, you need to bundle dependencies first.

Using esbuild

Important esbuild Options

flag
Bundle all dependencies into a single file
string
Mark QuickJS built-in modules (qjs:std, qjs:os, qjs:bjson) as external to avoid bundling errors
string
Output ES module format (recommended for QuickJS)
string
Target ECMAScript 2023 (QuickJS supports most ES2023 features)
flag
Minify the output to reduce executable size

Method 2: Using qjsc -e

For more control, you can use qjsc to generate a complete C program and compile it.

Basic Workflow

1

Compile to C

Use qjsc -e to generate C source code:
2

Compile C to Binary

Compile the C file with a C compiler:
3

Run

Execute the standalone binary:

Complete Example

Advantages of qjsc -e

  • Full control over C compilation flags
  • Can integrate with C modules
  • Can customize the runtime initialization
  • Can compile multiple JavaScript files together

With External C Modules

You can embed custom C modules in the executable:

Optimizations

Remove source code from bytecode to reduce size:
This removes the original JavaScript source but keeps debug info (line numbers, function names).

Comparison of Methods

Advanced Examples

Full Application with Bundler

With Standard Library Access

app.js

Platform-Specific Builds

Distribution

The resulting executables are self-contained and have the same runtime dependencies as the base qjs executable:
  • libc (standard C library)
  • libm (math library)
  • pthreads (if threading is enabled)
  • libdl (if dynamic module loading is enabled)
You can check dependencies with:

Troubleshooting

”Module not found” errors

If you get module errors when running a bundled executable:
  1. Make sure you used --external:qjs:* in esbuild
  2. Check that all imports use the correct module specifiers
  3. Verify the bundle works with qjs before compiling

Linking errors with qjsc

If you get linker errors when compiling C code:

Large executable size

To reduce executable size:
  1. Use --minify in esbuild
  2. Use -s or -ss flags with qjsc
  3. Use -P to exclude standard library (if not needed)
  4. Strip the final executable:

See Also

  • qjs - QuickJS interpreter CLI reference
  • qjsc - QuickJS compiler CLI reference