SkillAgentSearch skills...

Bramble

Purely functional build system and package manager

Install / Use

/learn @maxmcd/Bramble
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

<h1 align="center">Bramble</h1> <hr>

Bramble is a work-in-progress functional build system inspired by Nix.

Bramble is a functional build system that intends to be a user-friendly, robust, and reliable way to build software. Here are some if the ideas behind it:

  • Project Based: Every project has a bramble.toml and bramble.lock file that track dependencies and other metadata needed to build the project reliably.
  • Reproducible: All builds are assumed to be reproducible. Every build must consistently return the same output given the same input. You can write builds that aren't reproducible but they'll likely break things.
  • Rootless First:: Where possible, no root permissions are required to run. For sandboxing, user namespaces are used on Linux and sandbox-exec is used on macOS. Unclear how this will work beyond Linux and macOS.
  • Daemonless: Builds are executed directly and not handed off to a daemon.
  • Sandboxed: All builds are sandboxed, running software with Bramble will be sandboxed by default. Builds also take as little input as possible (no args, no environment variables, no network). Some of these might be relaxed as the project evolves, but things will hopefully stay locked down.
  • Dependencies: Dependencies are stored in repositories. You might reference them with load("github.com/maxmcd/busybox") in a build file or bramble build bitbucket.org/maxm/foo:foo from the command line. Dependencies are project specific.
  • Content-Addressable Store: Build outputs and build inputs are stored in directories that are named with the hash of their contents. This ensured build output can be verified and
  • Remote Build: Future support for remote build execution.
  • Starlark: The configuration language starlark is used to define builds.
  • Diverse Build Environment Support: Will have first class support for all major operating systems and potentially even support for the browser, webassembly, FAAS, and others. (Bramble is Linux-only at the moment).

Project Status

Many things are broken, would not expect this to work or be useful yet. The list of features seems to be solidifying so hopefully things will be more organized soon. If you have ideas or would like to contribute please open an issue.

Feature Status

  • [x] Basic Build Functionality
  • [x] Store Content Relocation
  • [ ] Sandboxing
    • [x] Linux
    • [ ] OSX
  • [x] "Fetch" Build Rules
    • [x] Fetch URL
    • [x] Fetch Git Repo
  • [x] Remote Dependencies
  • [ ] Remote Builds
  • [ ] Recursive Builds
  • [ ] Documentation Generation
  • [ ] Docker/OCI Container Build Output

Installation

Install with go get github.com/maxmcd/bramble or download a recent binary release. Linux is the only supported OS at the moment. macOS support should be coming soon, others much later.

Linux

In order for rootless/userspace sandboxing to work "User Namespaces" must be compiled and enabled in your kernel:

  • Confirm CONFIG_USER_NS=y is set in your kernel configuration (normally found in /proc/config.gz)
    $ cat /proc/config.gz | gzip -d | grep CONFIG_USER_NS
    CONFIG_USER_NS=y
    
  • Arch/Debian: echo 1 > /proc/sys/kernel/unprivileged_userns_clone
  • RHEL/CentOS 7: echo 28633 > /proc/sys/user/max_user_namespaces

Hello World

Here's an example project that downloads busybox and uses it to create a script that says "Hello world!".

./bramble.toml

[package]
name = "github.com/maxmcd/hello-example"
version = "0.0.1"

./default.bramble

def fetch_url(url):
    """
    fetch_url is a handy wrapper around the built-in fetch_url builder. It just
    takes the url you want to fetch.
    """
    return derivation(name="fetch-url", builder="fetch_url", env={"url": url})


def fetch_busybox():
    return fetch_url("https://brmbl.s3.amazonaws.com/busybox-x86_64.tar.gz")


def busybox():
    """
    busybox downloads the busybox binary and copies it to an output directory.
    Symlinks are then created for every command busybox supports.
    """
    return derivation(
        name="busybox",
        builder=fetch_busybox().out + "/busybox-x86_64",
        args=["sh", "./script.sh"],
        sources=files(["./script.sh"]),
        env={"busybox_download": fetch_busybox()},
    )


def hello_world():
    bb = busybox()
    PATH = "{}/bin".format(bb.out)

    return derivation(
        "say_hello_world",
        builder=bb.out + "/bin/sh",
        env=dict(PATH=PATH, busybox=bb.out),
        args=[
            "-c",
            """set -e

        mkdir -p $out/bin
        touch $out/bin/say-hello-world
        chmod +x $out/bin/say-hello-world

        echo "#!$busybox/bin/sh" > $out/bin/say-hello-world
        echo "$busybox/bin/echo Hello World!" >> $out/bin/say-hello-world

        # try it out
        $out/bin/say-hello-world
        """,
        ],
    )

./script.sh

set -e
$busybox_download/busybox-x86_64 mkdir $out/bin
$busybox_download/busybox-x86_64 cp $busybox_download/busybox-x86_64 $out/bin/busybox
cd $out/bin
for command in $(./busybox --list); do
	./busybox ln -s busybox $command
done

If you copy these files into a directory you can build it like so:

$ bramble build ./:hello_world
bramble path directory doesn't exist, creating
✔ busybox-x86_64.tar.gz - 332.830943ms
✔ busybox - 88.136237ms
✔ url_fetcher.tar.gz - 424.225793ms
✔ url_fetcher - 46.129651ms
✔ fetch-url - 313.461369ms
✔ busybox - 152.799168ms
✔ say_hello_world - 29.742436ms

Huh, what's confusing. What are all these builds in our output? Bramble needs to pull some dependencies itself in order to fetch and unpack the url provided. This is so that you can pin the internal functionality of bramble to a specific version. This isn't all hooked up yet, but for the moment you can see the internals being built in the build output.

Now that the build is complete you'll see that a bramble.toml file has been written to the project directory.

./bramble.lock

[URLHashes]
  "basic_fetch_url https://brmbl.s3.amazonaws.com/busybox-x86_64.tar.gz" = "uw5ichj6dhcccmcts6p7jq6etzlh5baf"
  "basic_fetch_url https://brmbl.s3.amazonaws.com/url_fetcher.tar.gz" = "p2vbvabkdqckjlm43rf7bfccdseizych"
  "fetch_url https://brmbl.s3.amazonaws.com/busybox-x86_64.tar.gz" = "uw5ichj6dhcccmcts6p7jq6etzlh5baf"

These are the three archives we had to download in order for the build to run. This will ensure that if we ever download these files again, the contents will match what we expect them to.

We can use bramble run to run the resulting script.

$ bramble run ./:hello_world say-hello-world
Hello World!

That's it! Your first build and run of a Bramble derivation.

Spec

This is a reference manual for Bramble. Bramble is a work-in-progress. I started writing this spec to solidify the major design decisions, but everything is still very much in flux. There are scattered notes in the notes folder as well.

Introduction

Bramble is a functional build system and package manager. Bramble is project-based, when you run a build or run a build output it must always be done in the context of a project.

Here are three example use-cases that Bramble hopes to support and support well.

  1. Running a build or a command related to a project. Often, code repositories want to explain how to build or run their software. Bramble aims to be one of the safest and most reliable ways to do that. A bramble build or bramble run within a project will use the bramble.toml, bramble.lock and source files to fetch dependencies from a cache or build them from source. Additionally bramble run commands are sandboxed by default, so Bramble should be a good choice to run unfamiliar software.
  2. Running arbitrary software from the internet. Running bramble run github.com/username/project:function binary will pull down software from that repo, build it, and run it within a sandbox on a local system. bramble run is sandboxed by default and aims to provide a safe and reproducible way to run arbitrary software on your system.
  3. Build a Docker/OCI container. Any bramble run call can be packaged up into a container containing only the bare-minimum dependencies for that program to run.
  4. Future use-cases. Support for WASM build environments, support for running builds in a browser. Tight integration with IDEs.

Project configuration

Every Project has a bramble.toml file that includes configuration information and a bramble.lock file that includes hashes and other metadata that are used to ensure that the project can be built reproducibly.

Package metadata

[package]
name =

Related Skills

View on GitHub
GitHub Stars193
CategoryDevelopment
Updated4d ago
Forks6

Languages

Go

Security Score

100/100

Audited on Mar 27, 2026

No findings