Skip to content

ALT-F4-LLC/vorpal

Repository files navigation

Vorpal

CI Release License npm

Vorpal is a build system that works the way you already write code. Define your build as a program -- not YAML, not a DSL -- using real SDKs in Rust, Go, or TypeScript. Vorpal handles hermetic execution, cross-platform targeting, content-addressed caching, and artifact distribution so you can focus on what you are building.

Contents

Install

curl -fsSL https://raw.githubusercontent.com/ALT-F4-LLC/vorpal/main/script/install.sh | sh

macOS (Apple Silicon, Intel) and Linux (x86_64, ARM64). The installer downloads the latest release, generates TLS keys, and starts background services.

Building from source? See the Contributing section. For detailed installation options, see the Installation Guide.

Quickstart

Create a new project and build your first artifact. For a more detailed walkthrough, see the Quickstart tutorial.

1. Create a project

mkdir hello-world && cd hello-world
vorpal init hello-world

Choose your language (Go, Rust, or TypeScript) when prompted. Vorpal scaffolds a working project with a Vorpal.toml and sample build config.

2. Build it

vorpal build hello-world

Vorpal compiles your config, resolves dependencies, and produces a content-addressed artifact. First builds download toolchains; subsequent builds are cached.

3. Run it

vorpal run hello-world

That is it. Your artifact is built, cached, and runnable.

SDK Examples

Vorpal build configs are real programs. Write them in the language your project already uses. See the full SDK guides for Rust, Go, and TypeScript.

Build an artifact

Define a build artifact targeting multiple platforms with a single config file.

TypeScript
import { ArtifactSystem, ConfigContext, TypeScript, TypeScriptDevelopmentEnvironment } from "@altf4llc/vorpal-sdk";

const SYSTEMS = [
  ArtifactSystem.AARCH64_DARWIN,
  ArtifactSystem.AARCH64_LINUX,
  ArtifactSystem.X8664_DARWIN,
  ArtifactSystem.X8664_LINUX,
];

const context = ConfigContext.create();

// Artifacts

await new TypeScriptDevelopmentEnvironment("example-shell", SYSTEMS)
  .build(context);

await new TypeScript("example", SYSTEMS)
  .withEntrypoint("src/main.ts")
  .withIncludes(["src", "bun.lock", "package.json", "tsconfig.json"])
  .build(context);

await context.run();
Rust
use anyhow::Result;
use vorpal_sdk::{
    api::artifact::ArtifactSystem::{Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux},
    artifact::language::rust::{Rust, RustDevelopmentEnvironment},
    context::get_context,
};

#[tokio::main]
async fn main() -> Result<()> {
    let ctx = &mut get_context().await?;
    let systems = vec![Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux];

    // Artifacts

    RustDevelopmentEnvironment::new("example-shell", systems.clone())
        .build(ctx)
        .await?;

    Rust::new("example", systems)
        .with_bins(vec!["example"])
        .with_includes(vec!["src", "Cargo.lock", "Cargo.toml"])
        .build(ctx)
        .await?;

    ctx.run().await
}
Go
package main

import (
    "log"

    api "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/api/artifact"
    "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/artifact/language"
    "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/config"
)

var systems = []api.ArtifactSystem{
    api.ArtifactSystem_AARCH64_DARWIN,
    api.ArtifactSystem_AARCH64_LINUX,
    api.ArtifactSystem_X8664_DARWIN,
    api.ArtifactSystem_X8664_LINUX,
}

func main() {
    ctx := config.GetContext()

    // Artifacts

	_, err := language.NewGoDevelopmentEnvironment("example-shell", systems).Build(ctx)
	if err != nil {
		log.Fatalf("error building development environment: %v", err)
	}

	_, err = language.NewGo("example", systems).
		WithBuildDirectory("cmd/example").
		WithIncludes([]string{"cmd", "go.mod", "go.sum"}).
		Build(ctx)
	if err != nil {
		log.Fatalf("error building: %v", err)
	}

    ctx.Run()
}

Dev & user environments

Create portable development shells and user-wide tool installations with pinned dependencies.

TypeScript
import {
  ConfigContext,
  ArtifactSystem,
  DevelopmentEnvironment,
  UserEnvironment,
} from "@altf4llc/vorpal-sdk";

const SYSTEMS = [
  ArtifactSystem.AARCH64_DARWIN,
  ArtifactSystem.AARCH64_LINUX,
  ArtifactSystem.X8664_DARWIN,
  ArtifactSystem.X8664_LINUX,
];

async function main() {
  const context = ConfigContext.create();

  await new DevelopmentEnvironment("my-project", SYSTEMS)
    .withEnvironments(["FOO=bar"])
    .build(context);

  await new UserEnvironment("my-home", SYSTEMS)
    .withSymlinks([["/path/to/local/bin/app", "$HOME/.vorpal/bin/app"]])
    .build(context);

  await context.run();
}

main().catch((e) => { console.error(e); process.exit(1); });
Rust
use anyhow::Result;
use vorpal_sdk::{
  api::artifact::ArtifactSystem::{Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux},
  artifact::{DevelopmentEnvironment, UserEnvironment},
  context::get_context,
};

#[tokio::main]
async fn main() -> Result<()> {
  let ctx = &mut get_context().await?;
  let systems = vec![Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux];

  DevelopmentEnvironment::new("my-project", systems.clone())
    .with_environments(vec!["FOO=bar".into()])
    .build(ctx).await?;

  UserEnvironment::new("my-home", systems)
    .with_symlinks(vec![("/path/to/local/bin/app", "$HOME/.vorpal/bin/app")])
    .build(ctx).await?;

  ctx.run().await
}
Go
package main

import (
  api "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/api/artifact"
  "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/artifact"
  "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/config"
)

var systems = []api.ArtifactSystem{
  api.ArtifactSystem_AARCH64_DARWIN,
  api.ArtifactSystem_AARCH64_LINUX,
  api.ArtifactSystem_X8664_DARWIN,
  api.ArtifactSystem_X8664_LINUX,
}

func main() {
  ctx := config.GetContext()

  artifact.NewDevelopmentEnvironment("my-project", systems).
    WithEnvironments([]string{"FOO=bar"}).
    Build(ctx)

  artifact.NewUserEnvironment("my-home", systems).
    WithSymlinks(map[string]string{"/path/to/local/bin/app": "$HOME/.vorpal/bin/app"}).
    Build(ctx)

  ctx.Run()
}

Activate:

  • Development environments: source generated bin/activate inside the artifact output.
  • User environments: run $HOME/.vorpal/bin/vorpal-activate, then source $HOME/.vorpal/bin/vorpal-activate-shell.

Custom executors

Swap the default Bash executor for Docker, Bubblewrap, or any custom binary.

TypeScript
import {
  ConfigContext,
  ArtifactSystem,
  Artifact,
  ArtifactStep,
} from "@altf4llc/vorpal-sdk";

const SYSTEMS = [
  ArtifactSystem.AARCH64_DARWIN,
  ArtifactSystem.AARCH64_LINUX,
  ArtifactSystem.X8664_DARWIN,
  ArtifactSystem.X8664_LINUX,
];

async function main() {
  const context = ConfigContext.create();

  const step = new ArtifactStep("docker")
    .withArguments([
      "run", "--rm", "-v", "$VORPAL_OUTPUT:/out",
      "alpine", "sh", "-lc", "echo hi > /out/hi.txt",
    ])
    .build();

  await new Artifact("example-docker", [step], SYSTEMS)
    .build(context);

  await context.run();
}

main().catch((e) => { console.error(e); process.exit(1); });
Rust
use anyhow::Result;
use vorpal_sdk::{
    api::artifact::ArtifactSystem::{Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux},
    artifact::{Artifact, ArtifactStep},
    context::get_context,
};

#[tokio::main]
async fn main() -> Result<()> {
    let ctx = &mut get_context().await?;
    let systems = vec![Aarch64Darwin, Aarch64Linux, X8664Darwin, X8664Linux];

    let step = ArtifactStep::new("docker")
        .with_arguments(vec![
            "run", "--rm", "-v", "$VORPAL_OUTPUT:/out",
            "alpine", "sh", "-lc", "echo hi > /out/hi.txt",
        ])
        .build();

    Artifact::new("example-docker", vec![step], systems).build(ctx).await?;

    ctx.run().await
}
Go
package main

import (
    "log"

    api "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/api/artifact"
    "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/artifact"
    "github.com/ALT-F4-LLC/vorpal/sdk/go/pkg/config"
)

var systems = []api.ArtifactSystem{
    api.ArtifactSystem_AARCH64_DARWIN,
    api.ArtifactSystem_AARCH64_LINUX,
    api.ArtifactSystem_X8664_DARWIN,
    api.ArtifactSystem_X8664_LINUX,
}

func main() {
    ctx := config.GetContext()

    step := artifact.NewArtifactStep("docker").
        WithArguments([]string{
            "run", "--rm", "-v", "$VORPAL_OUTPUT:/out",
            "alpine", "sh", "-lc",
            "echo hi > /out/hi.txt",
        }).
        Build()

    _, err := artifact.NewArtifact("example-docker",
        []*api.ArtifactStep{step}, systems).Build(ctx)
    if err != nil {
        log.Fatalf("error building artifact: %v", err)
    }

    ctx.Run()
}

Features

  • Config as code -- Your build config is a real program, not YAML. Write it in Rust, Go, or TypeScript with full IDE support.
  • Reproducible by default -- Content-addressed artifacts with hermetic build steps. Same inputs always produce the same output.
  • Cross-platform -- Target macOS (Apple Silicon + Intel) and Linux (x86_64 + ARM64) from a single config.
  • Built-in caching -- Artifacts are cached by content hash. Unchanged builds resolve instantly.
  • Dev environments -- Define project shells with pinned tools and env vars. Like direnv, but versioned and shareable.
  • Artifact registry -- Push, pull, and share artifacts with built-in registry support. Run artifacts directly with vorpal run.
  • Pluggable executors -- Build steps run in Bash by default. Swap in Docker, Bubblewrap, or any executor.

CLI Reference

Command Description
vorpal init <name> Initialize Vorpal in a directory
vorpal build <name> Build an artifact
vorpal run <alias> Run a built artifact from the store
vorpal config <action> Manage configuration settings (get, set, show)
vorpal login Login to an OAuth2 provider
vorpal inspect <digest> Inspect an artifact by digest
vorpal system keys generate Generate TLS keys
vorpal system services start Start Vorpal services (agent, registry, worker)
vorpal system prune Prune artifacts, sandboxes, and other resources

For full usage details and flags, run vorpal --help or vorpal <command> --help. See the complete CLI reference for more.

Documentation

Full documentation is available at docs.vorpal.build.

Resource Link
Installation guide docs.vorpal.build/getting-started/installation
Quickstart tutorial docs.vorpal.build/getting-started/quickstart
Architecture overview docs.vorpal.build/concepts/architecture
CLI reference docs.vorpal.build/reference/cli
Go SDK guide docs.vorpal.build/guides/go
Rust SDK guide docs.vorpal.build/guides/rust
TypeScript SDK guide docs.vorpal.build/guides/typescript

Contributing

Contributions are welcome. See docs/spec/ for project structure, coding standards, and review workflow.

# Build from source
./script/dev.sh make build

# Before submitting a PR
make format && make lint && make test

License

Apache 2.0

About

Build system that works as code.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors