Creating Standalone Executables
QuickJS-ng provides two methods for creating standalone executables from JavaScript code:- Using
qjs -c- Simple, single-file bundling (recommended) - Using
qjsc -e- Full C compilation with custom modules
Method 1: Using qjs -c (Recommended)
The simplest way to create a standalone executable is using theqjs interpreter’s compile flag.
Basic Usage
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 it3
Create Executable
The result is a self-contained executable with the same runtime dependencies as
qjsComplete 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.- Cross-compilation for different platforms
- Using a custom-built
qjswith specific features - Creating executables with different runtime configurations
Limitations
To work around this limitation, use a bundler:Bundling Multiple Files
Sinceqjs -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 errorsstring
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 useqjsc 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
- Strip Source Code
- Strip Debug Info
- Minimal Runtime
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 baseqjs 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:- Make sure you used
--external:qjs:*in esbuild - Check that all imports use the correct module specifiers
- Verify the bundle works with
qjsbefore compiling
Linking errors with qjsc
If you get linker errors when compiling C code:Large executable size
To reduce executable size:- Use
--minifyin esbuild - Use
-sor-ssflags with qjsc - Use
-Pto exclude standard library (if not needed) - Strip the final executable: