Giter Site home page Giter Site logo

bkg's Introduction


bkg


Package Bun apps into a single executable

GitHub Workflow Status



bkg is a CLI tool that can generate self-sufficient binaries from your Bun code for multiple platforms.

Usage

Fastest way to install:

curl -fsSL https://github.com/theseyan/bkg/raw/main/install.sh | sudo sh

OR, get the latest release for your platform (bkg_runtime- binaries are not required, they will be automatically downloaded).

Run bkg --help to get a list of options on usage:

Usage: bkg [options] <ProjectDirectory>
Example: bkg myProject -o myapp

Options:
  -h, --help             Display this help message.
  -o, --output <str>     Output file name
  -t, --target <str>     Target architecture to build for (default is Host)
  --targets              Display list of supported targets
  --runtime <str>        Path to custom Bun binary (not recommended)
  -v, --version          Display bkg version.
  <str>...

bkg.config.json

bkg assumes index.js to be the entry point of your application. This can be changed by creating bkg.config.json at the root directory of your project:

{
    "entry": "app.ts"
}

Why?

  • Distribute a single binary that can run without Bun or any external dependencies installed
  • Build executables for any platform supported by Bun
  • Around 1/2 the size of Bun runtime
  • Package any asset into the binary, not just scripts and modules
  • No performance regression except for the first startup
  • Although not yet possible, the goal is generating bytecode and the ability to distribute binaries stripped of sources

Link-Time Optimizations (LTO)

Since v0.0.4, bkg has support for an experimental LTO mode.

When LTO is enabled, bkg will attempt to statically analyze your code, bundle sources and perform tree shaking/minification at compile time. For large projects, this drastically reduces application size and boosts cold startup times.

To enable LTO, compile with --lto or add the following field to bkg.config.json:

{
    "lto": {
        "format": "cjs"
    }
}

Only reachable code is packaged into the executable; To include additional assets, use --include "path/to/files/*" flag or set the lto.includes field in configuration with a comma-separated list of glob file paths.

Differences from pkg

bkg and pkg (Node) have a number of differences arising either from a design decision or a Bun limitation:

  • Sources are not compiled to bytecode: Bun does not expose a JavascriptCore equivalent of v8::ScriptCompiler yet, hence sources are kept intact in the compiled executable.
  • File system: bkg does not embed a virtual filesystem but instead archives sources using the very fast LZ4 compression which are decompressed to a temporary location at runtime. This makes the resulting binary about 1/2 the size of Bun itself, while not having to keep the entire runtime in memory.
  • Import resolution: Unlike pkg, we do not recursively traverse through each import in the sources and package those files (yet). bkg will simply archive the entire source folder - this will change in version 1.0.

Key takeaways

  • bkg is not meant for very dynamic environments (for eg. serverless), as it adds considerable overhead to startup time. However, this overhead is only valid for the first start as the decompressed sources are cached in the filesystem onwards.
  • It is not recommended to perform fs operations with relative paths, as there is no guarantee where the sources may be placed at runtime. This will be fixed when I complete overriding some of fs default paths.
  • Generated executables are already stripped and must not be stripped again.

Building from source

bkg is written in Zig and compilation is fairly straightforward. The prerequisites are:

# Clone the repository and update submodules
git clone https://github.com/theseyan/bkg && cd bkg
git submodule update --init --recursive

# Build for x86_64-linux
zig build -Drelease-fast -Dtarget=x86_64-linux

# [Optional] Build runtime for x86_64-linux & strip it
zig build-exe -target x86_64-linux src/bkg_runtime.zig -fstrip -lc deps/lz4/lib/lz4.c deps/microtar/src/microtar.c --pkg-begin known-folders deps/known-folders/known-folders.zig --pkg-end

# Run bkg
./zig-out/bin/bkg --help

# OR, build runtime and CLI for all platforms
# Generated executables are placed in /build
chmod +x build.sh && ./build.sh

Todo

Release v0.1.0:

  • Switch to LZ4 high compression variant that compresses more but doesn't affect decompression speed (and shaves off 7MB!)
  • Runtime: Stream decompressed buffer directly to microtar instead of through the filesystem. This will greatly improve startup time.
  • Compiler: Stream archive directly to LZ4_compress_HC instead of through the filesystem
  • Use zfetch instead of cURL
  • JSON configuration file
  • Pass CLI args to javascript
  • Named app directory containing the CRC32 hash of project sources. This will fix outdated cached code being executed.
  • Override Bun default variables with an injected JS entry point

Roadmap: v1.0

  • Optimizer/Bundler based on esbuild to bundle entire source tree into a handful of JS files. This is important because currently our biggest bottleneck is decompression speed with lots of files (>1000 files) which is common in projects with node_modules. Ideally, this will be replaced by Bun's own bundler.
  • Runtime hash checking against inflated sources to prevent execution of modified scripts
  • Prettier CLI output with colors & loaders
  • Prebuild, postbuild options and CLI argument counterparts of bkg.config.json
  • Pass Bun CLI flags
  • Fork a custom build of Bun with only the JS runtime to further reduce binary size
  • Multithreaded decompression for even faster cold starts

Optimizer Progress: See bOptimizer.

bkg's People

Contributors

deluxor avatar theseyan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

Forkers

deluxor gtrabanco

bkg's Issues

Publish as package

Can this be available through bun install by publishing in npmjs?

Installation would be easier by using bun add bkg.

error: module not found

I got the compilation to work but when I try to run the binary, I get the following error. Any ideas what's going wrong since the error message is just a bit vague ;)

error: module not found "/tmp/.test_runtime_3722025239/index.js"
The following command exited with error code 1:
error: CommandFailed

I'm running this on Ubuntu 20.04 in WSL2.

error: RenameAcrossMountPoints

Is this something to do with how I set up bun and bkg on linux? I keep getting the same error, I have tried bkg v0.0.2 and v0.0.3, but still no luck.

bkg ./ -o testing

No target was specified, building for x86_64-linux
Downloading bun-v0.4.0 for target x86_64-linux...
Runtime already exists, skipping
Downloading bkg runtime v0.0.4 for target x86_64-linux...
bkg runtime already exists, skipping
Building archive...
Writing file README.md with 221 bytes
Writing file tsconfig.json with 416 bytes
bun.lockb is executable
Writing file bun.lockb with 1187 bytes
Writing file package.json with 121 bytes
Writing directory node_modules
Writing directory node_modules/bun-types
Writing file node_modules/bun-types/README.md with 1017 bytes
Writing file node_modules/bun-types/types.d.ts with 1899784 bytes
Writing file node_modules/bun-types/package.json with 375 bytes
Writing file index.ts with 30 bytes
Configuration file not found, using default
Adding Bun binary...
Finalized archive
Compressing archive...
Compressed to 37711283 bytes
Calculated CRC32 hash: 483121177
Writing archive to binary...
Written 37711283 bytes to binary
Finalizing binary...
Done
error: RenameAcrossMountPoints

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.